// Copyright 2009 Ryan Dahl #ifndef NODE_IO_H_ #define NODE_IO_H_ #include #include namespace node { class IOWatcher { public: static void Initialize(v8::Handle target); protected: static v8::Persistent constructor_template; IOWatcher() { ev_init(&watcher_, IOWatcher::Callback); watcher_.data = this; } ~IOWatcher() { assert(!ev_is_active(&watcher_)); } static v8::Handle New(const v8::Arguments& args); static v8::Handle Start(const v8::Arguments& args); 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 Stop(); ev_io watcher_; v8::Persistent handle_; }; } // namespace node #endif // NODE_IO_H_