#define GOLD_WORKQUEUE_H
#include "gold-threads.h"
-#include "options.h"
#include "fileread.h"
namespace gold
{
+class General_options;
class Task;
class Workqueue;
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.
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
// 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
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();