Add an API to pump the message loop to libplatform
authorjochen@chromium.org <jochen@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 3 Jul 2014 09:33:36 +0000 (09:33 +0000)
committerjochen@chromium.org <jochen@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 3 Jul 2014 09:33:36 +0000 (09:33 +0000)
BUG=none
LOG=n
R=marja@chromium.org

Review URL: https://codereview.chromium.org/363303002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22187 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

include/libplatform/libplatform.h
src/libplatform/default-platform.cc
src/libplatform/default-platform.h
test/cctest/cctest.gyp
test/cctest/test-libplatform-default-platform.cc [new file with mode: 0644]

index 5867a3268267c3aabadbe8665d13ad0e55520153..2125e9746b93ca724a9d0cf6992ca2cfc00e5e33 100644 (file)
@@ -21,6 +21,17 @@ namespace platform {
 v8::Platform* CreateDefaultPlatform(int thread_pool_size = 0);
 
 
+/**
+ * Pumps the message loop for the given isolate.
+ *
+ * The caller has to make sure that this is called from the right thread.
+ * Returns true if a task was executed, and false otherwise. This call does
+ * not block if no task is pending. The |platform| has to be created using
+ * |CreateDefaultPlatform|.
+ */
+bool PumpMessageLoop(v8::Platform* platform, v8::Isolate* isolate);
+
+
 }  // namespace platform
 }  // namespace v8
 
index 9a2c30dcdefa769913205aac21ab68352efaf8e9..a05ec7dedb102525ba6c21c3d6d79bada6a6d793 100644 (file)
@@ -23,6 +23,11 @@ v8::Platform* CreateDefaultPlatform(int thread_pool_size) {
 }
 
 
+bool PumpMessageLoop(v8::Platform* platform, v8::Isolate* isolate) {
+  return reinterpret_cast<DefaultPlatform*>(platform)->PumpMessageLoop(isolate);
+}
+
+
 const int DefaultPlatform::kMaxThreadPoolSize = 4;
 
 
@@ -39,6 +44,14 @@ DefaultPlatform::~DefaultPlatform() {
       delete *i;
     }
   }
+  for (std::map<v8::Isolate*, std::queue<Task*> >::iterator i =
+           main_thread_queue_.begin();
+       i != main_thread_queue_.end(); ++i) {
+    while (!i->second.empty()) {
+      delete i->second.front();
+      i->second.pop();
+    }
+  }
 }
 
 
@@ -61,6 +74,24 @@ void DefaultPlatform::EnsureInitialized() {
     thread_pool_.push_back(new WorkerThread(&queue_));
 }
 
+
+bool DefaultPlatform::PumpMessageLoop(v8::Isolate* isolate) {
+  Task* task = NULL;
+  {
+    base::LockGuard<base::Mutex> guard(&lock_);
+    std::map<v8::Isolate*, std::queue<Task*> >::iterator it =
+        main_thread_queue_.find(isolate);
+    if (it == main_thread_queue_.end() || it->second.empty()) {
+      return false;
+    }
+    task = it->second.front();
+    it->second.pop();
+  }
+  task->Run();
+  delete task;
+  return true;
+}
+
 void DefaultPlatform::CallOnBackgroundThread(Task *task,
                                              ExpectedRuntime expected_runtime) {
   EnsureInitialized();
@@ -69,9 +100,8 @@ void DefaultPlatform::CallOnBackgroundThread(Task *task,
 
 
 void DefaultPlatform::CallOnForegroundThread(v8::Isolate* isolate, Task* task) {
-  // TODO(jochen): implement.
-  task->Run();
-  delete task;
+  base::LockGuard<base::Mutex> guard(&lock_);
+  main_thread_queue_[isolate].push(task);
 }
 
 } }  // namespace v8::platform
index c5f6fae3abaf79a97d405f5837774af1fd408b7f..fcbb14c36c436084a3be43f2e23258532cd64e60 100644 (file)
@@ -5,6 +5,8 @@
 #ifndef V8_LIBPLATFORM_DEFAULT_PLATFORM_H_
 #define V8_LIBPLATFORM_DEFAULT_PLATFORM_H_
 
+#include <map>
+#include <queue>
 #include <vector>
 
 #include "include/v8-platform.h"
@@ -28,11 +30,13 @@ class DefaultPlatform : public Platform {
 
   void EnsureInitialized();
 
+  bool PumpMessageLoop(v8::Isolate* isolate);
+
   // v8::Platform implementation.
   virtual void CallOnBackgroundThread(
-      Task *task, ExpectedRuntime expected_runtime) V8_OVERRIDE;
-  virtual void CallOnForegroundThread(v8::Isolate *isolate,
-                                      Task *task) V8_OVERRIDE;
+      Tasktask, ExpectedRuntime expected_runtime) V8_OVERRIDE;
+  virtual void CallOnForegroundThread(v8::Isolateisolate,
+                                      Tasktask) V8_OVERRIDE;
 
  private:
   static const int kMaxThreadPoolSize;
@@ -42,6 +46,7 @@ class DefaultPlatform : public Platform {
   int thread_pool_size_;
   std::vector<WorkerThread*> thread_pool_;
   TaskQueue queue_;
+  std::map<v8::Isolate*, std::queue<Task*> > main_thread_queue_;
 
   DISALLOW_COPY_AND_ASSIGN(DefaultPlatform);
 };
index 4ba1fa602283fb23ec2ace019e46cc42272fe6f5..ac2d625aae7459e3258517d557fe64c2aaa7ef3d 100644 (file)
@@ -85,6 +85,7 @@
         'test-heap.cc',
         'test-heap-profiler.cc',
         'test-hydrogen-types.cc',
+        'test-libplatform-default-platform.cc',
         'test-libplatform-task-queue.cc',
         'test-libplatform-worker-thread.cc',
         'test-list.cc',
diff --git a/test/cctest/test-libplatform-default-platform.cc b/test/cctest/test-libplatform-default-platform.cc
new file mode 100644 (file)
index 0000000..dac6db2
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/libplatform/default-platform.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/test-libplatform.h"
+
+using namespace v8::internal;
+using namespace v8::platform;
+
+
+TEST(DefaultPlatformMessagePump) {
+  TaskCounter task_counter;
+
+  DefaultPlatform platform;
+
+  TestTask* task = new TestTask(&task_counter, true);
+
+  CHECK(!platform.PumpMessageLoop(CcTest::isolate()));
+
+  platform.CallOnForegroundThread(CcTest::isolate(), task);
+
+  CHECK_EQ(1, task_counter.GetCount());
+  CHECK(platform.PumpMessageLoop(CcTest::isolate()));
+  CHECK_EQ(0, task_counter.GetCount());
+  CHECK(!platform.PumpMessageLoop(CcTest::isolate()));
+}