summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFedor Indutny <fedor.indutny@gmail.com>2013-08-14 17:57:38 +0200
committerBert Belder <bertbelder@gmail.com>2013-08-14 17:57:38 +0200
commitf6308f3ee68fff48b94b030d5e9045db2bf6c3f7 (patch)
treed3535fd94dc688e162d4f9ddf2da6ddadc66523a
parentb1acb2ebd6e023e00f5df23c46e66513ffda04a8 (diff)
downloadnode-fsevents-fix.tar.gz
fsevents: FSEvents is most likely not thread-safefsevents-fix
Perform all operation with FSEventStream in the same thread, where it'll be used. Conflicts: src/unix/fsevents.c
-rw-r--r--deps/uv/src/unix/fsevents.c69
-rw-r--r--deps/uv/src/unix/kqueue.c1
2 files changed, 44 insertions, 26 deletions
diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c
index b6d274675..a29b030fa 100644
--- a/deps/uv/src/unix/fsevents.c
+++ b/deps/uv/src/unix/fsevents.c
@@ -192,17 +192,6 @@ void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
void uv__fsevents_schedule(void* arg) {
uv_fs_event_t* handle;
-
- handle = arg;
- FSEventStreamScheduleWithRunLoop(handle->cf_eventstream,
- handle->loop->cf_loop,
- kCFRunLoopDefaultMode);
- FSEventStreamStart(handle->cf_eventstream);
- uv_sem_post(&handle->cf_sem);
-}
-
-
-int uv__fsevents_init(uv_fs_event_t* handle) {
FSEventStreamContext ctx;
FSEventStreamRef ref;
CFStringRef path;
@@ -210,6 +199,8 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
CFAbsoluteTime latency;
FSEventStreamCreateFlags flags;
+ handle = arg;
+
/* Initialize context */
ctx.version = 0;
ctx.info = handle;
@@ -217,16 +208,13 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
ctx.release = NULL;
ctx.copyDescription = NULL;
- /* Get absolute path to file */
- handle->realpath = realpath(handle->filename, NULL);
- if (handle->realpath != NULL)
- handle->realpath_len = strlen(handle->realpath);
-
/* Initialize paths array */
path = CFStringCreateWithCString(NULL,
handle->filename,
CFStringGetSystemEncoding());
+ assert(path != NULL);
paths = CFArrayCreate(NULL, (const void**)&path, 1, NULL);
+ assert(paths != NULL);
latency = 0.15;
@@ -240,8 +228,42 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
kFSEventStreamEventIdSinceNow,
latency,
flags);
+ assert(ref != NULL);
handle->cf_eventstream = ref;
+ FSEventStreamScheduleWithRunLoop(handle->cf_eventstream,
+ handle->loop->cf_loop,
+ kCFRunLoopDefaultMode);
+ if (!FSEventStreamStart(handle->cf_eventstream))
+ abort();
+}
+
+
+static void uv__fsevents_unschedule(void* arg) {
+ uv_fs_event_t* handle;
+
+ handle = arg;
+
+ /* Stop emitting events */
+ FSEventStreamStop(handle->cf_eventstream);
+
+ /* Release stream */
+ FSEventStreamInvalidate(handle->cf_eventstream);
+ FSEventStreamRelease(handle->cf_eventstream);
+ handle->cf_eventstream = NULL;
+
+ /* Notify main thread that we're done here */
+ uv_sem_post(&handle->cf_sem);
+}
+
+
+int uv__fsevents_init(uv_fs_event_t* handle) {
+ /* Get absolute path to file */
+ handle->realpath = realpath(handle->filename, NULL);
+ if (handle->realpath != NULL)
+ handle->realpath_len = strlen(handle->realpath);
+
+ handle->cf_eventstream = NULL;
/*
* Events will occur in other thread.
* Initialize callback for getting them back into event loop's thread
@@ -266,21 +288,16 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
int uv__fsevents_close(uv_fs_event_t* handle) {
- if (handle->cf_eventstream == NULL)
+ if (handle->cf_cb == NULL)
return -1;
- /* Ensure that event stream was scheduled */
- uv_sem_wait(&handle->cf_sem);
-
- /* Stop emitting events */
- FSEventStreamStop(handle->cf_eventstream);
+ uv__cf_loop_signal(handle->loop, uv__fsevents_unschedule, handle);
- /* Release stream */
- FSEventStreamInvalidate(handle->cf_eventstream);
- FSEventStreamRelease(handle->cf_eventstream);
- handle->cf_eventstream = NULL;
+ /* Wait for deinitialization */
+ uv_sem_wait(&handle->cf_sem);
uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) free);
+ handle->cf_cb = NULL;
/* Free data in queue */
UV__FSEVENTS_WALK(handle, {
diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c
index 378903a62..2feb4babd 100644
--- a/deps/uv/src/unix/kqueue.c
+++ b/deps/uv/src/unix/kqueue.c
@@ -307,6 +307,7 @@ int uv_fs_event_init(uv_loop_t* loop,
#if defined(__APPLE__)
/* Nullify field to perform checks later */
+ handle->cf_cb = NULL;
handle->cf_eventstream = NULL;
handle->realpath = NULL;
handle->realpath_len = 0;