*** empty log message ***
[deliverable/binutils-gdb.git] / gold / workqueue.h
index 5949cf5f4396d9502337192e8f9d36bd684b1cb1..ed7a5b00d7ddf030abe295497a2ef91d2b2170a6 100644 (file)
 #define GOLD_WORKQUEUE_H
 
 #include "gold-threads.h"
-#include "options.h"
 #include "fileread.h"
 
 namespace gold
 {
 
+class General_options;
 class Task;
 class Workqueue;
 
@@ -146,6 +146,27 @@ class Task_block_token
   Workqueue* workqueue_;
 };
 
+// An object which implements an RAII lock for any object which
+// supports lock and unlock methods.
+
+template<typename Obj>
+class Task_lock_obj
+{
+ public:
+  Task_lock_obj(Obj& obj)
+    : obj_(obj)
+  { this->obj_.lock(); }
+
+  ~Task_lock_obj()
+  { this->obj_.unlock(); }
+
+ private:
+  Task_lock_obj(const Task_lock_obj&);
+  Task_lock_obj& operator=(const Task_lock_obj&);
+
+  Obj& obj_;
+};
+
 // An abstract class used to lock Task_tokens using RAII.  A typical
 // implementation would simply have a set of members of type
 // Task_read_token, Task_write_token, and Task_block_token.
@@ -209,21 +230,22 @@ class Task_locker_block : public Task_locker
   Task_block_token block_token_;
 };
 
-// A version of Task_locker which may be used to hold a lock on a
-// File_read.
+// A version of Task_locker which may be used to hold a lock on any
+// object which supports lock() and unlock() methods.
 
-class Task_locker_file : public Task_locker
+template<typename Obj>
+class Task_locker_obj : public Task_locker
 {
  public:
-  Task_locker_file(File_read& file)
-    : file_lock_(file)
+  Task_locker_obj(Obj& obj)
+    : obj_lock_(obj)
   { }
 
  private:
-  Task_locker_file(const Task_locker_file&);
-  Task_locker_file& operator=(const Task_locker_file&);
+  Task_locker_obj(const Task_locker_obj&);
+  Task_locker_obj& operator=(const Task_locker_obj&);
 
-  File_read_lock file_lock_;
+  Task_lock_obj<Obj> obj_lock_;
 };
 
 // The superclass for tasks to be placed on the workqueue.  Each
@@ -264,6 +286,62 @@ class Task
   // Run the task.
   virtual void
   run(Workqueue*) = 0;
+
+ private:
+  Task(const Task&);
+  Task& operator=(const Task&);
+};
+
+// A simple task which waits for a blocker and then runs a function.
+
+class Task_function_runner
+{
+ public:
+  virtual ~Task_function_runner()
+  { }
+
+  virtual void
+  run(Workqueue*) = 0;
+};
+
+class Task_function : public Task
+{
+ public:
+  // Both points should be allocated using new, and will be deleted
+  // after the task runs.
+  Task_function(Task_function_runner* runner, Task_token* blocker)
+    : runner_(runner), blocker_(blocker)
+  { }
+
+  ~Task_function()
+  {
+    delete this->runner_;
+    delete this->blocker_;
+  }
+
+  // The standard task methods.
+
+  // Wait until the task is unblocked.
+  Is_runnable_type
+  is_runnable(Workqueue*)
+  { return this->blocker_->is_blocked() ? IS_BLOCKED : IS_RUNNABLE; }
+
+  // This type of task does not normally hold any locks.
+  virtual Task_locker*
+  locks(Workqueue*)
+  { return NULL; }
+
+  // Run the action.
+  void
+  run(Workqueue* workqueue)
+  { this->runner_->run(workqueue); }
+
+ private:
+  Task_function(const Task_function&);
+  Task_function& operator=(const Task_function&);
+
+  Task_function_runner* runner_;
+  Task_token* blocker_;
 };
 
 // The workqueue
@@ -280,6 +358,11 @@ class Workqueue
   void
   queue(Task*);
 
+  // Add a new task to the front of the work queue.  It will be the
+  // next task to run if it is ready.
+  void
+  queue_front(Task*);
+
   // Process all the tasks on the work queue.
   void
   process();
This page took 0.024609 seconds and 4 git commands to generate.