Created
November 15, 2012 23:30
-
-
Save croteb/4082355 to your computer and use it in GitHub Desktop.
winsockwatcher
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "mdns.hpp" | |
#include "winsock_watcher.hpp" | |
#include <node.h> | |
#include <node_version.h> | |
using namespace v8; | |
#if NODE_VERSION_AT_LEAST(0, 7, 8) | |
// Nothing | |
#else | |
namespace node { | |
Handle<Value> | |
MakeCallback(const Handle<Object> object, | |
const Handle<Function> callback, | |
int argc, | |
Handle<Value> argv[]) { | |
HandleScope scope; | |
// TODO Hook for long stack traces to be made here. | |
TryCatch try_catch; | |
Local<Value> ret = callback->Call(object, argc, argv); | |
if (try_catch.HasCaught()) { | |
FatalException(try_catch); | |
return Undefined(); | |
} | |
return scope.Close(ret); | |
} | |
} // namespace node | |
#endif | |
namespace node_mdns { | |
Persistent<String> callback_symbol; | |
Handle<Value> Calleback(const Arguments& args) { | |
return Undefined(); | |
}; | |
void WinsockWatcher::Initialize(Handle<Object> target) { | |
printf("top of initialize\n"); | |
Local<FunctionTemplate> t = FunctionTemplate::New(New); | |
Local<String> symbol = String::NewSymbol("WinsockWatcher"); | |
t->SetClassName(symbol); | |
t->InstanceTemplate()->SetInternalFieldCount(1); | |
NODE_SET_PROTOTYPE_METHOD(t, "set", WinsockWatcher::Set); | |
NODE_SET_PROTOTYPE_METHOD(t, "start", WinsockWatcher::Start); | |
NODE_SET_PROTOTYPE_METHOD(t, "stop", WinsockWatcher::Stop); | |
target->Set(symbol, t->GetFunction()); | |
callback_symbol = NODE_PSYMBOL("callback"); | |
//target->Set(String::NewSymbol("callback"), FunctionTemplate::New(Calleback)->GetFunction()); | |
printf("bottom of initialize\n"); | |
} | |
Handle<Value> WinsockWatcher::Start(const Arguments& args) { | |
HandleScope scope; | |
WinsockWatcher *io = ObjectWrap::Unwrap<WinsockWatcher>(args.Holder()); | |
io->Start(); | |
printf("returned from local start in cpp\n"); | |
return Undefined(); | |
} | |
void WinsockWatcher::Start() { | |
printf("starting watcher from cpp\n"); | |
if (!ev_is_active(&watcher_)) { | |
printf("is not active from cpp\n"); | |
ev_io_start(EV_DEFAULT_UC_ &watcher_); | |
//uv_poll_init(uv_default_loop(), &watcher_.handle, 0); | |
//uv_poll_start(&watcher_.handle,UV_READABLE,io_event); | |
printf("ev_io_start called from cpp\n"); | |
Ref(); | |
} | |
} | |
void WinsockWatcher::Callback(EV_P_ ev_io *w, int revents) { | |
HandleScope scope; | |
printf("top of callback"); | |
/* | |
WinsockWatcher *io = static_cast<WinsockWatcher*>(w->data); | |
assert(w == &io->watcher_); | |
HandleScope scope; | |
Local<Value> callback_v = io->handle_->Get(callback_symbol); | |
if (!callback_v->IsFunction()) { | |
io->Stop(); | |
return; | |
} | |
Local<Function> callback = Local<Function>::Cast(callback_v); | |
TryCatch try_catch; | |
Local<Value> argv[2]; | |
argv[0] = Local<Value>::New(revents & UV_READ ? True() : False()); | |
argv[1] = Local<Value>::New(revents & UV_WRITE ? True() : False()); | |
printf("calling callback\n"); | |
callback->Call(io->handle_, 2, argv); | |
printf("returned from callback\n"); | |
if (try_catch.HasCaught()) { | |
node::FatalException(try_catch); | |
} | |
*/ | |
WinsockWatcher *io = static_cast<WinsockWatcher*>(w->data); | |
assert(w == &io->watcher_); | |
Local<Value> callback_v = io->handle_->Get(callback_symbol); | |
if (!callback_v->IsFunction()) { | |
io->Stop(); | |
return; | |
} | |
Local<Function> callback = Local<Function>::Cast(callback_v); | |
Local<Value> argv[2]; | |
argv[0] = Local<Value>::New(revents & UV_READABLE ? True() : False()); | |
argv[1] = Local<Value>::New(revents & UV_WRITABLE ? True() : False()); | |
node::MakeCallback(io->handle_, callback, ARRAY_SIZE(argv), argv); | |
} | |
Handle<Value> WinsockWatcher::Stop(const Arguments& args) { | |
HandleScope scope; | |
WinsockWatcher *io = ObjectWrap::Unwrap<WinsockWatcher>(args.Holder()); | |
io->Stop(); | |
return Undefined(); | |
} | |
void WinsockWatcher::Stop() { | |
printf("stopping from cpp.\n"); | |
if (ev_is_active(&watcher_)) { | |
printf("watcher is active from cpp\n"); | |
ev_io_stop(EV_DEFAULT_UC_ &watcher_); | |
Unref(); | |
} | |
} | |
v8::Handle<v8::Value> | |
WinsockWatcher::New(const v8::Arguments & args) { | |
HandleScope scope; | |
WinsockWatcher *s = new WinsockWatcher(); | |
s->Wrap(args.This()); | |
return args.This(); | |
} | |
Handle<Value> WinsockWatcher::Set(const Arguments& args) { | |
HandleScope scope; | |
printf("top of set function\n"); | |
WinsockWatcher *io = ObjectWrap::Unwrap<WinsockWatcher>(args.Holder()); | |
if (!args[0]->IsInt32()) { | |
return ThrowException(Exception::TypeError( | |
String::New("First arg should be a file descriptor."))); | |
} | |
int fd = args[0]->Int32Value(); | |
if (!args[1]->IsBoolean()) { | |
return ThrowException(Exception::TypeError( | |
String::New("Second arg should boolean (readable)."))); | |
} | |
int events = 0; | |
if (args[1]->IsTrue()) events |= UV_READABLE; | |
if (!args[2]->IsBoolean()) { | |
return ThrowException(Exception::TypeError( | |
String::New("Third arg should boolean (writable)."))); | |
} | |
if (args[2]->IsTrue()) events |= UV_WRITABLE; | |
printf("middle of function: %i, %i\n",fd,events); | |
//assert(!io->watcher_.active); | |
assert(!ev_is_active(&io->watcher_)); | |
ev_io_set(&io->watcher_, fd, events); | |
printf("bottom of set function\n"); | |
return Undefined(); | |
} | |
/* | |
void InitAll(Handle<Object> target) { | |
WinsockWatcher::Initialize(target); | |
} | |
NODE_MODULE(dns_sd_bindings, WinsockWatcher::Initialize); | |
*/ | |
} // end of namespace node_mdns |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef NODE_MDNS_WINSOCK_WATCHER_INCLUDED | |
#define NODE_MDNS_WINSOCK_WATCHER_INCLUDED | |
#define BUILDING_NODE_EXTENSION | |
#include "uv.h" | |
#undef ev_init | |
#undef ev_set_cb | |
#undef ev_set_priority | |
#undef ev_is_active | |
#undef ev_timer_init | |
#undef ev_timer_set | |
#undef ev_io_init | |
#undef ev_io_set | |
#undef EV_P | |
#undef EV_P_ | |
#undef EV_A | |
#undef EV_A_ | |
#undef EV_DEFAULT | |
#undef EV_DEFAULT_ | |
#undef EV_DEFAULT_UC | |
#undef EV_DEFAULT_UC_ | |
#define EV_P void | |
#define EV_P_ | |
#define EV_A | |
#define EV_A_ | |
#define EV_DEFAULT | |
#define EV_DEFAULT_ | |
#define EV_DEFAULT_UC | |
#define EV_DEFAULT_UC_ | |
#define ev_io __ev_io | |
#define ev_io_init __ev_io_init | |
#define ev_io_set __ev_io_set | |
#define ev_io_start __ev_io_start | |
#define ev_io_stop __ev_io_stop | |
#define ev_init(w, cb_) \ | |
do { \ | |
void* data = (w)->data; \ | |
memset((w), 0, sizeof(*(w))); \ | |
(w)->data = data; \ | |
(w)->cb = (cb_); \ | |
} \ | |
while (0) | |
#define ev_set_cb(w, cb_) \ | |
do \ | |
(w)->cb = (cb_); \ | |
while (0) | |
#define ev_is_active(w) \ | |
(uv_is_active((uv_handle_t*) &(w)->handle)) | |
#define __uv_container_of(ptr, type, field) \ | |
((type*) ((char*) (ptr) - offsetof(type, field))) | |
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) | |
struct __ev_io; | |
typedef struct __ev_io __ev_io; | |
typedef void (*__ev_io_cb)(__ev_io*, int); | |
struct __ev_io { | |
__ev_io_cb cb; | |
void* data; | |
int flags; /* bit 1 == initialized, yes or no? */ | |
uv_poll_t handle; | |
int fd; | |
int events; | |
}; | |
inline static void __uv_poll_cb(uv_poll_t* handle, int status, int events) { | |
printf("__uv_poll_cb\n"); | |
__ev_io* w = __uv_container_of(handle, __ev_io, handle); | |
w->cb(w, events); | |
(void) status; | |
} | |
inline static void __ev_io_stop(__ev_io* w) { | |
printf("ev_io_stop\n"); | |
uv_poll_stop(&w->handle); | |
} | |
inline static void __ev_io_set(__ev_io* w, int fd, int events) { | |
printf("ev_io_set,%x,%i,%x\n",w,fd,events); | |
w->fd = fd; | |
w->events = events; | |
printf("ev_io_set from struct,%x,%i,%x\n",w,w->fd,w->events); | |
} | |
static void io_event(uv_poll_t* w, int status, int revents){ | |
printf("handling io_event\n"); | |
} | |
namespace node_mdns { | |
class WinsockWatcher : public node::ObjectWrap { | |
public: | |
static void Initialize(v8::Handle<v8::Object> target); | |
__ev_io watcher_; | |
static void Callback(EV_P_ ev_io *watcher, int revents); | |
protected: | |
static v8::Handle<v8::Value> New(const v8::Arguments & args); | |
static v8::Handle<v8::Value> Set(const v8::Arguments & args); | |
static v8::Handle<v8::Value> Start(const v8::Arguments& args); | |
static v8::Handle<v8::Value> Stop(const v8::Arguments& args); | |
WinsockWatcher() : ObjectWrap() { | |
printf("WinsockWatcher constructor: %x\n",WinsockWatcher::Callback); | |
ev_init(&watcher_, WinsockWatcher::Callback); | |
watcher_.data = this; | |
} | |
~WinsockWatcher() { | |
printf("WinsockWatcher destructor\n"); | |
ev_io_stop(EV_DEFAULT_UC_ &watcher_); | |
assert(!ev_is_active(&watcher_)); | |
//assert(!ev_is_pending(&watcher_)); | |
} | |
private: | |
void Start(); | |
void Stop(); | |
}; | |
} // end of namespace node_mdns | |
inline static void __ev_io_start(__ev_io* w) { | |
printf("ev_io_start\n"); | |
printf("starting ev_poll_start, %x,%i,%x,%x,%x\n",w,w->fd,&w->handle,w->events,&__uv_poll_cb); | |
if (!(w->flags & 1)) { | |
printf("calling uv_poll_init\n"); | |
uv_poll_init(uv_default_loop(), &w->handle, w->fd); | |
w->flags |= 1; | |
} | |
printf("starting uv_poll_start, %x,%i,%x,%x,%x,%x\n",w,w->fd,&w->handle,w->events,&__uv_poll_cb, io_event); | |
//uv_poll_start(&w->handle,UV_READABLE,io_event); | |
//printf("after starting uv_poll_start, %x,%i,%x,%x,%x,%x\n",w,w->fd,&w->handle,w->events,&__uv_poll_cb, io_event); | |
uv_poll_start(&w->handle, w->events, __uv_poll_cb); | |
} | |
#endif // NODE_MDNS_WINSOCK_WATCHER_INCLUDED |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment