|
|
@ -25,6 +25,11 @@ |
|
|
|
#include <string.h> |
|
|
|
#include <stdlib.h> |
|
|
|
|
|
|
|
// Poll interval in milliseconds. 5007 is what libev used to use. It's a little
|
|
|
|
// on the slow side but let's stick with it for now, keep behavioral changes to
|
|
|
|
// a minimum.
|
|
|
|
#define DEFAULT_POLL_INTERVAL 5007 |
|
|
|
|
|
|
|
namespace node { |
|
|
|
|
|
|
|
using namespace v8; |
|
|
@ -33,6 +38,7 @@ Persistent<FunctionTemplate> StatWatcher::constructor_template; |
|
|
|
static Persistent<String> onchange_sym; |
|
|
|
static Persistent<String> onstop_sym; |
|
|
|
|
|
|
|
|
|
|
|
void StatWatcher::Initialize(Handle<Object> target) { |
|
|
|
HandleScope scope; |
|
|
|
|
|
|
@ -48,18 +54,24 @@ void StatWatcher::Initialize(Handle<Object> target) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void StatWatcher::Callback(EV_P_ ev_stat *watcher, int revents) { |
|
|
|
assert(revents == EV_STAT); |
|
|
|
StatWatcher *handler = static_cast<StatWatcher*>(watcher->data); |
|
|
|
assert(watcher == &handler->watcher_); |
|
|
|
void StatWatcher::Callback(uv_fs_poll_t* handle, |
|
|
|
int status, |
|
|
|
const uv_statbuf_t* prev, |
|
|
|
const uv_statbuf_t* curr) { |
|
|
|
StatWatcher* wrap = container_of(handle, StatWatcher, watcher_); |
|
|
|
assert(handle == &wrap->watcher_); |
|
|
|
HandleScope scope; |
|
|
|
Local<Value> argv[2]; |
|
|
|
argv[0] = BuildStatsObject(&watcher->attr); |
|
|
|
argv[1] = BuildStatsObject(&watcher->prev); |
|
|
|
Local<Value> argv[3]; |
|
|
|
argv[0] = BuildStatsObject(curr); |
|
|
|
argv[1] = BuildStatsObject(prev); |
|
|
|
argv[2] = Integer::New(status); |
|
|
|
if (status == -1) { |
|
|
|
SetErrno(uv_last_error(wrap->watcher_.loop)); |
|
|
|
} |
|
|
|
if (onchange_sym.IsEmpty()) { |
|
|
|
onchange_sym = NODE_PSYMBOL("onchange"); |
|
|
|
} |
|
|
|
MakeCallback(handler->handle_, onchange_sym, ARRAY_SIZE(argv), argv); |
|
|
|
MakeCallback(wrap->handle_, onchange_sym, ARRAY_SIZE(argv), argv); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -69,7 +81,7 @@ Handle<Value> StatWatcher::New(const Arguments& args) { |
|
|
|
} |
|
|
|
|
|
|
|
HandleScope scope; |
|
|
|
StatWatcher *s = new StatWatcher(); |
|
|
|
StatWatcher* s = new StatWatcher(); |
|
|
|
s->Wrap(args.Holder()); |
|
|
|
return args.This(); |
|
|
|
} |
|
|
@ -82,27 +94,23 @@ Handle<Value> StatWatcher::Start(const Arguments& args) { |
|
|
|
return ThrowException(Exception::TypeError(String::New("Bad arguments"))); |
|
|
|
} |
|
|
|
|
|
|
|
StatWatcher *handler = ObjectWrap::Unwrap<StatWatcher>(args.Holder()); |
|
|
|
StatWatcher* wrap = ObjectWrap::Unwrap<StatWatcher>(args.Holder()); |
|
|
|
String::Utf8Value path(args[0]); |
|
|
|
|
|
|
|
assert(handler->path_ == NULL); |
|
|
|
handler->path_ = strdup(*path); |
|
|
|
|
|
|
|
ev_tstamp interval = 0.; |
|
|
|
if (args[2]->IsInt32()) { |
|
|
|
interval = NODE_V8_UNIXTIME(args[2]); |
|
|
|
uint32_t interval = DEFAULT_POLL_INTERVAL; |
|
|
|
if (args[2]->IsUint32()) { |
|
|
|
interval = args[2]->Uint32Value(); |
|
|
|
} |
|
|
|
|
|
|
|
ev_stat_set(&handler->watcher_, handler->path_, interval); |
|
|
|
ev_stat_start(EV_DEFAULT_UC_ &handler->watcher_); |
|
|
|
uv_fs_poll_start(&wrap->watcher_, Callback, *path, interval); |
|
|
|
|
|
|
|
handler->persistent_ = args[1]->IsTrue(); |
|
|
|
wrap->persistent_ = args[1]->IsTrue(); |
|
|
|
|
|
|
|
if (!handler->persistent_) { |
|
|
|
ev_unref(EV_DEFAULT_UC); |
|
|
|
if (!wrap->persistent_) { |
|
|
|
uv_unref(reinterpret_cast<uv_handle_t*>(&wrap->watcher_)); |
|
|
|
} |
|
|
|
|
|
|
|
handler->Ref(); |
|
|
|
wrap->Ref(); |
|
|
|
|
|
|
|
return Undefined(); |
|
|
|
} |
|
|
@ -110,24 +118,20 @@ Handle<Value> StatWatcher::Start(const Arguments& args) { |
|
|
|
|
|
|
|
Handle<Value> StatWatcher::Stop(const Arguments& args) { |
|
|
|
HandleScope scope; |
|
|
|
StatWatcher *handler = ObjectWrap::Unwrap<StatWatcher>(args.Holder()); |
|
|
|
StatWatcher* wrap = ObjectWrap::Unwrap<StatWatcher>(args.Holder()); |
|
|
|
if (onstop_sym.IsEmpty()) { |
|
|
|
onstop_sym = NODE_PSYMBOL("onstop"); |
|
|
|
} |
|
|
|
MakeCallback(handler->handle_, onstop_sym, 0, NULL); |
|
|
|
handler->Stop(); |
|
|
|
MakeCallback(wrap->handle_, onstop_sym, 0, NULL); |
|
|
|
wrap->Stop(); |
|
|
|
return Undefined(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void StatWatcher::Stop () { |
|
|
|
if (watcher_.active) { |
|
|
|
if (!persistent_) ev_ref(EV_DEFAULT_UC); |
|
|
|
ev_stat_stop(EV_DEFAULT_UC_ &watcher_); |
|
|
|
free(path_); |
|
|
|
path_ = NULL; |
|
|
|
Unref(); |
|
|
|
} |
|
|
|
if (!uv_is_active(reinterpret_cast<uv_handle_t*>(&watcher_))) return; |
|
|
|
uv_fs_poll_stop(&watcher_); |
|
|
|
Unref(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|