summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/fs.js12
-rw-r--r--node.gyp2
-rw-r--r--src/node.cc1
-rw-r--r--src/node_file.cc6
-rw-r--r--src/node_stat_watcher.cc68
-rw-r--r--src/node_stat_watcher.h15
-rw-r--r--test/pummel/test-fs-watch-file.js6
-rw-r--r--test/pummel/test-watch-file.js5
8 files changed, 52 insertions, 63 deletions
diff --git a/lib/fs.js b/lib/fs.js
index 17c79c9357..8b3b6b233e 100644
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -876,7 +876,13 @@ function StatWatcher() {
var self = this;
this._handle = new binding.StatWatcher();
- this._handle.onchange = function(current, previous) {
+ // uv_fs_poll is a little more powerful than ev_stat but we curb it for
+ // the sake of backwards compatibility
+ var oldStatus = -1;
+
+ this._handle.onchange = function(current, previous, newStatus) {
+ if (oldStatus == -1 && newStatus == -1) return;
+ oldStatus = newStatus;
self.emit('change', current, previous);
};
@@ -905,10 +911,6 @@ function inStatWatchers(filename) {
fs.watchFile = function(filename) {
- if (isWindows) {
- throw new Error('use fs.watch api instead');
- }
-
var stat;
var options;
var listener;
diff --git a/node.gyp b/node.gyp
index 3906d664bd..0816442e47 100644
--- a/node.gyp
+++ b/node.gyp
@@ -82,6 +82,7 @@
'src/node_main.cc',
'src/node_os.cc',
'src/node_script.cc',
+ 'src/node_stat_watcher.cc',
'src/node_string.cc',
'src/node_zlib.cc',
'src/pipe_wrap.cc',
@@ -208,7 +209,6 @@
'defines': [ '__POSIX__' ],
'sources': [
'src/node_signal_watcher.cc',
- 'src/node_stat_watcher.cc',
'src/node_io_watcher.cc',
]
}],
diff --git a/src/node.cc b/src/node.cc
index 991f63b31e..d71a21b693 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -69,7 +69,6 @@ typedef int mode_t;
#include "node_http_parser.h"
#ifdef __POSIX__
# include "node_signal_watcher.h"
-# include "node_stat_watcher.h"
#endif
#include "node_constants.h"
#include "node_javascript.h"
diff --git a/src/node_file.cc b/src/node_file.cc
index f48790a093..7e8badf5c2 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -22,9 +22,7 @@
#include "node.h"
#include "node_file.h"
#include "node_buffer.h"
-#ifdef __POSIX__
-# include "node_stat_watcher.h"
-#endif
+#include "node_stat_watcher.h"
#include "req_wrap.h"
#include <fcntl.h>
@@ -984,9 +982,7 @@ void InitFs(Handle<Object> target) {
oncomplete_sym = NODE_PSYMBOL("oncomplete");
-#ifdef __POSIX__
StatWatcher::Initialize(target);
-#endif
}
} // end namespace node
diff --git a/src/node_stat_watcher.cc b/src/node_stat_watcher.cc
index efe3939e9b..33190895a9 100644
--- a/src/node_stat_watcher.cc
+++ b/src/node_stat_watcher.cc
@@ -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();
}
diff --git a/src/node_stat_watcher.h b/src/node_stat_watcher.h
index 2b2d1331de..5b09d2f04c 100644
--- a/src/node_stat_watcher.h
+++ b/src/node_stat_watcher.h
@@ -23,7 +23,7 @@
#define NODE_STAT_WATCHER_H_
#include "node.h"
-#include "uv-private/ev.h"
+#include "uv.h"
namespace node {
@@ -36,14 +36,11 @@ class StatWatcher : ObjectWrap {
StatWatcher() : ObjectWrap() {
persistent_ = false;
- path_ = NULL;
- ev_init(&watcher_, StatWatcher::Callback);
- watcher_.data = this;
+ uv_fs_poll_init(uv_default_loop(), &watcher_);
}
~StatWatcher() {
Stop();
- assert(path_ == NULL);
}
static v8::Handle<v8::Value> New(const v8::Arguments& args);
@@ -51,13 +48,15 @@ class StatWatcher : ObjectWrap {
static v8::Handle<v8::Value> Stop(const v8::Arguments& args);
private:
- static void Callback(EV_P_ ev_stat *watcher, int revents);
+ static void Callback(uv_fs_poll_t* handle,
+ int status,
+ const uv_statbuf_t* prev,
+ const uv_statbuf_t* curr);
void Stop();
- ev_stat watcher_;
+ uv_fs_poll_t watcher_;
bool persistent_;
- char *path_;
};
} // namespace node
diff --git a/test/pummel/test-fs-watch-file.js b/test/pummel/test-fs-watch-file.js
index 49455a197f..3df28af56f 100644
--- a/test/pummel/test-fs-watch-file.js
+++ b/test/pummel/test-fs-watch-file.js
@@ -19,12 +19,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-// fs.watchFile is not available on Windows
-if (process.platform === 'win32') {
- process.exit(0);
-}
-
-
var common = require('../common');
var assert = require('assert');
var path = require('path');
diff --git a/test/pummel/test-watch-file.js b/test/pummel/test-watch-file.js
index 3cdc3d67f5..1a3d854101 100644
--- a/test/pummel/test-watch-file.js
+++ b/test/pummel/test-watch-file.js
@@ -19,11 +19,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-// fs.watchFile is not available on Windows
-if (process.platform === 'win32') {
- process.exit(0);
-}
-
var common = require('../common');
var assert = require('assert');