blob: 2f461c405c05ba4636ee7a7513a172a8b4c30097 [file] [log] [blame]
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: morlovich@google.com (Maksim Orlovich)
//
// This contains Worker, which is a base class for classes managing running
// of work in background.
#ifndef PAGESPEED_KERNEL_THREAD_WORKER_H_
#define PAGESPEED_KERNEL_THREAD_WORKER_H_
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/string_util.h"
namespace net_instaweb {
class Function;
class ThreadSystem;
class Waveform;
// This class is a base for various mechanisms of running things in background.
//
// If you just want to run something in background, you want to use a subclass
// of this, such as a SlowWorker or QueuedWorker instance.
//
// Subclasses should implement bool PermitQueue() and provide an appropriate
// wrapper around QueueIfPermitted().
class Worker {
public:
// Tries to start the work thread (if it hasn't been started already).
void Start();
// Returns true if there was a job running or any jobs queued at the time
// this function was called.
bool IsBusy();
// Finishes the currently running jobs, and deletes any queued jobs.
// No further jobs will be accepted after this call either; they will
// just be canceled. It is safe to call this method multiple times.
void ShutDown();
// Sets up a timed-variable statistic indicating the current queue depth.
//
// This must be called prior to starting the thread.
void set_queue_size_stat(Waveform* x) { queue_size_ = x; }
protected:
Worker(StringPiece thread_name, ThreadSystem* runtime);
virtual ~Worker();
// If IsPermitted() returns true, queues up the given closure to be run,
// takes ownership of closure, and returns true. (Also wakes up the work
// thread to actually run it if it's idle)
//
// Otherwise it merely returns false, and doesn't do anything else.
bool QueueIfPermitted(Function* closure);
// Subclasses should implement this method to implement the policy
// on whether to run given tasks or not.
virtual bool IsPermitted(Function* closure) = 0;
// Returns the number of jobs, including any running and queued jobs.
// The lock semantics here are as follows:
// - QueueIfPermitted calls IsPermitted with lock held.
// - NumJobs assumes lock to be held.
// => It's safe to call NumJobs from within IsPermitted if desired.
int NumJobs();
private:
class WorkThread;
friend class WorkThread;
// This is called whenever a task is added or removed from the queue.
void UpdateQueueSizeStat(int size);
scoped_ptr<WorkThread> thread_;
Waveform* queue_size_;
DISALLOW_COPY_AND_ASSIGN(Worker);
};
} // namespace net_instaweb
#endif // PAGESPEED_KERNEL_THREAD_WORKER_H_