| Index: src/JsEngineInternal.h | 
| =================================================================== | 
| --- a/src/JsEngineInternal.h | 
| +++ b/src/JsEngineInternal.h | 
| @@ -6,6 +6,7 @@ | 
| #include <v8.h> | 
| #include <array> | 
| #include "AllocatedArray.h" | 
| +#include "Scheduler.h" | 
| #include "V8Upgrade.h" | 
| class PersistentValueArray | 
| @@ -60,6 +61,9 @@ | 
| } | 
| }; | 
| +struct ImmediateSingleUseThreadType {}; ///< Marker class for scheduling policy | 
| +extern const ImmediateSingleUseThreadType ImmediateSingleUseThread; ///< Dummy constant for scheduling policy | 
| + | 
| /** | 
| * \par Implementation Notes | 
| */ | 
| @@ -71,6 +75,64 @@ | 
| */ | 
| v8::Persistent<v8::Context> context; | 
| + /** | 
| + * A task within our scheduler. | 
| + * | 
| + * TODO: Move this class into the scheduler proper. | 
| + */ | 
| + class Task | 
| + { | 
| + /** | 
| + * Shared pointer to our engine keeps it in existence | 
| + * for the duration of the execution of this task. | 
| + */ | 
| + AdblockPlus::JsEnginePtr engine; | 
| + /** | 
| + * The body of the task, containing its main function. | 
| + * This is the class where tasks are heap-allocated for polymorphism. | 
| + */ | 
| + std::shared_ptr<TaskFunctionInterface> body; | 
| + | 
| + public: | 
| + /** | 
| + * Constructor makes a new shared pointer to the engine | 
| + * but copies the task body. | 
| + */ | 
| + Task(JsEngineInternal* engine, std::shared_ptr<TaskFunctionInterface>&& body) | 
| + : engine(engine->shared_from_this()), body(body) | 
| + {} | 
| + | 
| + /* | 
| + * Call operator allows conversion to std::function<void()> so that | 
| + * we don't have to change the scheduler just yet. | 
| + */ | 
| + void operator()() | 
| + { | 
| + if (body) | 
| + { | 
| + body->operator()(); | 
| + } | 
| + } | 
| + }; | 
| + | 
| + /** | 
| + * Scheduler for tasks executed under the current engine. | 
| + */ | 
| + SchedulerT<SingleUseWorker> scheduler; | 
| + | 
| + /** | 
| + * Schedule a task, internal version. | 
| + * | 
| + * This version relies upon the external version of this function | 
| + * to allocate a shared pointer to the task. | 
| + * | 
| + * @param task | 
| + * Task to execute. All v8 handles must refer to the present engine. | 
| + * @param ImmediateSingleUseThreadType | 
| + * The schedule policy--create a new thread and discard it afterwards. | 
| + */ | 
| + void ScheduleTaskInternal(std::shared_ptr<TaskFunctionInterface>&& body); | 
| + | 
| public: | 
| JsEngineInternal(const AdblockPlus::ScopedV8IsolatePtr& isolate); | 
| @@ -85,6 +147,29 @@ | 
| v8::Local<v8::Object> GetGlobalObject(); | 
| /** | 
| + * Schedule a task with these policies: | 
| + * - timing policy: start execution immediately. | 
| + * - threading policy: run the task in a single-use thread. | 
| + * | 
| + * @param task | 
| + * Task to execute. All v8 handles must refer to the present engine. | 
| + * @param ImmediateSingleUseThreadType | 
| + * The schedule policy--create a new thread and discard it afterwards. | 
| + */ | 
| + template<class T> | 
| + void ScheduleTask(T&& task, ImmediateSingleUseThreadType) | 
| + { | 
| + ScheduleTaskInternal(std::static_pointer_cast<TaskFunctionInterface>(std::make_shared<T>(task))); | 
| + } | 
| + | 
| + /** | 
| + * Block until there are no more tasks running in the scheduler. | 
| + * | 
| + * Note: this function does not prevent new tasks from being scheduled. | 
| + */ | 
| + void WaitForQuietScheduler(); | 
| + | 
| + /** | 
| * Create a JavaScript function that binds to a C++ callback. | 
| * | 
| * We save a copy of a pointer to the present instance when we |