Don't use gcd to post tasks to main thread.
This commit is contained in:
parent
5bbb41415a
commit
41ff753339
3 changed files with 33 additions and 14 deletions
2
atom.gyp
2
atom.gyp
|
@ -130,8 +130,8 @@
|
||||||
'common/api/object_life_monitor.h',
|
'common/api/object_life_monitor.h',
|
||||||
'common/node_bindings.cc',
|
'common/node_bindings.cc',
|
||||||
'common/node_bindings.h',
|
'common/node_bindings.h',
|
||||||
|
'common/node_bindings_mac.cc',
|
||||||
'common/node_bindings_mac.h',
|
'common/node_bindings_mac.h',
|
||||||
'common/node_bindings_mac.mm',
|
|
||||||
'common/options_switches.cc',
|
'common/options_switches.cc',
|
||||||
'common/options_switches.h',
|
'common/options_switches.h',
|
||||||
'common/platform_util.h',
|
'common/platform_util.h',
|
||||||
|
|
|
@ -26,7 +26,8 @@ void UvNoOp(uv_async_t* handle, int status) {
|
||||||
|
|
||||||
NodeBindingsMac::NodeBindingsMac(bool is_browser)
|
NodeBindingsMac::NodeBindingsMac(bool is_browser)
|
||||||
: NodeBindings(is_browser),
|
: NodeBindings(is_browser),
|
||||||
loop_(uv_default_loop()),
|
message_loop_(NULL),
|
||||||
|
uv_loop_(uv_default_loop()),
|
||||||
kqueue_(kqueue()),
|
kqueue_(kqueue()),
|
||||||
embed_closed_(false) {
|
embed_closed_(false) {
|
||||||
}
|
}
|
||||||
|
@ -43,7 +44,7 @@ void NodeBindingsMac::PrepareMessageLoop() {
|
||||||
|
|
||||||
// Add dummy handle for libuv, otherwise libuv would quit when there is
|
// Add dummy handle for libuv, otherwise libuv would quit when there is
|
||||||
// nothing to do.
|
// nothing to do.
|
||||||
uv_async_init(loop_, &dummy_uv_handle_, UvNoOp);
|
uv_async_init(uv_loop_, &dummy_uv_handle_, UvNoOp);
|
||||||
|
|
||||||
// Start worker that will interrupt main loop when having uv events.
|
// Start worker that will interrupt main loop when having uv events.
|
||||||
uv_sem_init(&embed_sem_, 0);
|
uv_sem_init(&embed_sem_, 0);
|
||||||
|
@ -53,8 +54,12 @@ void NodeBindingsMac::PrepareMessageLoop() {
|
||||||
void NodeBindingsMac::RunMessageLoop() {
|
void NodeBindingsMac::RunMessageLoop() {
|
||||||
DCHECK(!is_browser_ || BrowserThread::CurrentlyOn(BrowserThread::UI));
|
DCHECK(!is_browser_ || BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||||
|
|
||||||
loop_->data = this;
|
// The MessageLoop should have been created, remember the one in main thread.
|
||||||
loop_->on_watcher_queue_updated = OnWatcherQueueChanged;
|
message_loop_ = base::MessageLoop::current();
|
||||||
|
|
||||||
|
// Get notified when libuv's watcher queue changes.
|
||||||
|
uv_loop_->data = this;
|
||||||
|
uv_loop_->on_watcher_queue_updated = OnWatcherQueueChanged;
|
||||||
|
|
||||||
// Run uv loop for once to give the uv__io_poll a chance to add all events.
|
// Run uv loop for once to give the uv__io_poll a chance to add all events.
|
||||||
UvRunOnce();
|
UvRunOnce();
|
||||||
|
@ -68,18 +73,24 @@ void NodeBindingsMac::UvRunOnce() {
|
||||||
v8::Context::Scope context_scope(node::g_context);
|
v8::Context::Scope context_scope(node::g_context);
|
||||||
|
|
||||||
// Deal with uv events.
|
// Deal with uv events.
|
||||||
int r = uv_run(loop_, (uv_run_mode)(UV_RUN_ONCE | UV_RUN_NOWAIT));
|
int r = uv_run(uv_loop_, (uv_run_mode)(UV_RUN_ONCE | UV_RUN_NOWAIT));
|
||||||
if (r == 0 || loop_->stop_flag != 0)
|
if (r == 0 || uv_loop_->stop_flag != 0)
|
||||||
MessageLoop::current()->QuitWhenIdle(); // Quit from uv.
|
message_loop_->QuitWhenIdle(); // Quit from uv.
|
||||||
|
|
||||||
// Tell the worker thread to continue polling.
|
// Tell the worker thread to continue polling.
|
||||||
uv_sem_post(&embed_sem_);
|
uv_sem_post(&embed_sem_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeBindingsMac::WakeupMainThread() {
|
||||||
|
DCHECK(message_loop_);
|
||||||
|
message_loop_->PostTask(FROM_HERE, base::Bind(&NodeBindingsMac::UvRunOnce,
|
||||||
|
base::Unretained(this)));
|
||||||
|
}
|
||||||
|
|
||||||
void NodeBindingsMac::EmbedThreadRunner(void *arg) {
|
void NodeBindingsMac::EmbedThreadRunner(void *arg) {
|
||||||
NodeBindingsMac* self = static_cast<NodeBindingsMac*>(arg);
|
NodeBindingsMac* self = static_cast<NodeBindingsMac*>(arg);
|
||||||
|
|
||||||
uv_loop_t* loop = self->loop_;
|
uv_loop_t* loop = self->uv_loop_;
|
||||||
|
|
||||||
// Add uv's backend fd to kqueue.
|
// Add uv's backend fd to kqueue.
|
||||||
struct kevent ev;
|
struct kevent ev;
|
||||||
|
@ -105,9 +116,7 @@ void NodeBindingsMac::EmbedThreadRunner(void *arg) {
|
||||||
} while (r == -1 && errno == EINTR);
|
} while (r == -1 && errno == EINTR);
|
||||||
|
|
||||||
// Deal with event in main thread.
|
// Deal with event in main thread.
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
self->WakeupMainThread();
|
||||||
self->UvRunOnce();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
#include "common/node_bindings.h"
|
#include "common/node_bindings.h"
|
||||||
#include "vendor/node/deps/uv/include/uv.h"
|
#include "vendor/node/deps/uv/include/uv.h"
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
class MessageLoop;
|
||||||
|
}
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
class NodeBindingsMac : public NodeBindings {
|
class NodeBindingsMac : public NodeBindings {
|
||||||
|
@ -23,14 +27,20 @@ class NodeBindingsMac : public NodeBindings {
|
||||||
// Run the libuv loop for once.
|
// Run the libuv loop for once.
|
||||||
void UvRunOnce();
|
void UvRunOnce();
|
||||||
|
|
||||||
|
// Make the main thread run libuv loop.
|
||||||
|
void WakeupMainThread();
|
||||||
|
|
||||||
// Thread to poll uv events.
|
// Thread to poll uv events.
|
||||||
static void EmbedThreadRunner(void *arg);
|
static void EmbedThreadRunner(void *arg);
|
||||||
|
|
||||||
// Called when uv's watcher queue changes.
|
// Called when uv's watcher queue changes.
|
||||||
static void OnWatcherQueueChanged(uv_loop_t* loop);
|
static void OnWatcherQueueChanged(uv_loop_t* loop);
|
||||||
|
|
||||||
// Main thread's loop.
|
// Main thread's MessageLoop.
|
||||||
uv_loop_t* loop_;
|
base::MessageLoop* message_loop_;
|
||||||
|
|
||||||
|
// Main thread's libuv loop.
|
||||||
|
uv_loop_t* uv_loop_;
|
||||||
|
|
||||||
// Kqueue to poll for uv's backend fd.
|
// Kqueue to poll for uv's backend fd.
|
||||||
int kqueue_;
|
int kqueue_;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue