/*
 * 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_
