diff --git a/src/node_io_watcher.cc b/src/node_io_watcher.cc index 2f05c7fd4e2..baf46411bc9 100644 --- a/src/node_io_watcher.cc +++ b/src/node_io_watcher.cc @@ -34,6 +34,7 @@ void IOWatcher::Initialize(Handle target) { void IOWatcher::Callback(EV_P_ ev_io *w, int revents) { IOWatcher *io = static_cast(w->data); assert(w == &io->watcher_); + assert(!(revents & EV_ERROR)); HandleScope scope; Local callback_v = io->handle_->Get(callback_symbol); @@ -50,7 +51,9 @@ void IOWatcher::Callback(EV_P_ ev_io *w, int revents) { argv[0] = Local::New(revents & EV_READ ? True() : False()); argv[1] = Local::New(revents & EV_WRITE ? True() : False()); + io->Ref(); callback->Call(io->handle_, 2, argv); + io->Unref(); if (try_catch.HasCaught()) { FatalException(try_catch); @@ -76,27 +79,16 @@ Handle IOWatcher::New(const Arguments& args) { } -Handle IOWatcher::Start(const Arguments& args) { - HandleScope scope; - - IOWatcher *io = Unwrap(args.Holder()); - - ev_io_start(EV_DEFAULT_UC_ &io->watcher_); - assert(ev_is_active(&io->watcher_)); - - return Undefined(); -} - Handle IOWatcher::Set(const Arguments& args) { HandleScope scope; - IOWatcher *io = Unwrap(args.Holder()); - if (!args[0]->IsInt32()) { return ThrowException(Exception::TypeError( String::New("First arg should be a file descriptor."))); } + IOWatcher *io = ObjectWrap::Unwrap(args.This()); + int fd = args[0]->Int32Value(); if (!args[1]->IsBoolean()) { @@ -120,19 +112,38 @@ Handle IOWatcher::Set(const Arguments& args) { return Undefined(); } + +Handle IOWatcher::Start(const Arguments& args) { + HandleScope scope; + IOWatcher *io = ObjectWrap::Unwrap(args.This()); + io->Start(); + return Undefined(); +} + + Handle IOWatcher::Stop(const Arguments& args) { HandleScope scope; - IOWatcher *io = Unwrap(args.This()); + IOWatcher *io = ObjectWrap::Unwrap(args.This()); io->Stop(); return Undefined(); } +void IOWatcher::Start () { + if (!ev_is_active(&watcher_)) { + ev_io_start(EV_DEFAULT_UC_ &watcher_); + Ref(); + } + assert(ev_is_active(&watcher_)); +} + + void IOWatcher::Stop () { if (ev_is_active(&watcher_)) { ev_io_stop(EV_DEFAULT_UC_ &watcher_); - assert(!ev_is_active(&watcher_)); + Unref(); } + assert(!ev_is_active(&watcher_)); } diff --git a/src/node_io_watcher.h b/src/node_io_watcher.h index d1d9d2dc2a3..95a135e7660 100644 --- a/src/node_io_watcher.h +++ b/src/node_io_watcher.h @@ -7,20 +7,22 @@ namespace node { -class IOWatcher { +class IOWatcher : ObjectWrap { public: static void Initialize(v8::Handle target); protected: static v8::Persistent constructor_template; - IOWatcher() { + IOWatcher() : ObjectWrap() { ev_init(&watcher_, IOWatcher::Callback); watcher_.data = this; } ~IOWatcher() { + Stop(); assert(!ev_is_active(&watcher_)); + assert(!ev_is_pending(&watcher_)); } static v8::Handle New(const v8::Arguments& args); @@ -28,47 +30,13 @@ class IOWatcher { static v8::Handle Stop(const v8::Arguments& args); static v8::Handle Set(const v8::Arguments& args); - inline void Wrap(v8::Handle handle) { - assert(handle_.IsEmpty()); - assert(handle->InternalFieldCount() > 0); - handle_ = v8::Persistent::New(handle); - handle_->SetInternalField(0, v8::External::New(this)); - MakeWeak(); - } - - inline void MakeWeak(void) { - handle_.MakeWeak(this, WeakCallback); - } - - - private: static void Callback(EV_P_ ev_io *watcher, int revents); - static void WeakCallback (v8::Persistent value, void *data) - { - IOWatcher *io = static_cast(data); - assert(value == io->handle_); - if (!ev_is_active(&io->watcher_)) { - value.Dispose(); - delete io; - } else { - //value.ClearWeak(); - io->MakeWeak(); - } - } - - static IOWatcher* Unwrap(v8::Handle handle) { - assert(!handle.IsEmpty()); - assert(handle->InternalFieldCount() > 0); - return static_cast(v8::Handle::Cast( - handle->GetInternalField(0))->Value()); - } - + void Start(); void Stop(); ev_io watcher_; - v8::Persistent handle_; }; } // namespace node