Skip to content
This repository was archived by the owner on May 4, 2018. It is now read-only.

Commit 38df93c

Browse files
committed
unix: revert recent FSEvent changes
This commit reverts the following commits: 983fa68 darwin: fix 10.6 build error in fsevents.c 684e212 fsevents: use shared FSEventStream ea4cb77 fsevents: FSEvents is most likely not thread-safe 9bae606 darwin: create fsevents thread on demand Several people have reported stability issues on OS X 10.8 and bus errors on the 10.9 developer preview. See also nodejs/node-v0.x-archive#6296 and nodejs/node-v0.x-archive#6251.
1 parent 11d8011 commit 38df93c

File tree

5 files changed

+270
-532
lines changed

5 files changed

+270
-532
lines changed

include/uv-private/uv-darwin.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636

3737
#define UV_PLATFORM_LOOP_FIELDS \
3838
uv_thread_t cf_thread; \
39-
void* _cf_reserved; \
40-
void* cf_state; \
39+
void* cf_cb; \
40+
void* cf_loop; \
4141
uv_mutex_t cf_mutex; \
4242
uv_sem_t cf_sem; \
4343
ngx_queue_t cf_signals; \
@@ -47,10 +47,10 @@
4747
char* realpath; \
4848
int realpath_len; \
4949
int cf_flags; \
50-
void* cf_event; \
50+
void* cf_eventstream; \
5151
uv_async_t* cf_cb; \
52-
ngx_queue_t cf_member; \
53-
uv_sem_t _cf_reserved; \
52+
ngx_queue_t cf_events; \
53+
uv_sem_t cf_sem; \
5454
uv_mutex_t cf_mutex; \
5555

5656
#define UV_STREAM_PRIVATE_PLATFORM_FIELDS \

src/unix/darwin.c

+129-2
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,153 @@
2828
#include <ifaddrs.h>
2929
#include <net/if.h>
3030

31+
#include <CoreFoundation/CFRunLoop.h>
32+
3133
#include <mach/mach.h>
3234
#include <mach/mach_time.h>
3335
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
3436
#include <sys/resource.h>
3537
#include <sys/sysctl.h>
3638
#include <unistd.h> /* sysconf */
3739

40+
/* Forward declarations */
41+
static void uv__cf_loop_runner(void* arg);
42+
static void uv__cf_loop_cb(void* arg);
43+
44+
typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
45+
struct uv__cf_loop_signal_s {
46+
void* arg;
47+
cf_loop_signal_cb cb;
48+
ngx_queue_t member;
49+
};
50+
3851

3952
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
40-
loop->cf_state = NULL;
53+
CFRunLoopSourceContext ctx;
54+
int r;
4155

4256
if (uv__kqueue_init(loop))
4357
return -1;
4458

59+
loop->cf_loop = NULL;
60+
if ((r = uv_mutex_init(&loop->cf_mutex)))
61+
return r;
62+
if ((r = uv_sem_init(&loop->cf_sem, 0)))
63+
return r;
64+
ngx_queue_init(&loop->cf_signals);
65+
66+
memset(&ctx, 0, sizeof(ctx));
67+
ctx.info = loop;
68+
ctx.perform = uv__cf_loop_cb;
69+
loop->cf_cb = CFRunLoopSourceCreate(NULL, 0, &ctx);
70+
71+
if ((r = uv_thread_create(&loop->cf_thread, uv__cf_loop_runner, loop)))
72+
return r;
73+
74+
/* Synchronize threads */
75+
uv_sem_wait(&loop->cf_sem);
76+
assert(ACCESS_ONCE(CFRunLoopRef, loop->cf_loop) != NULL);
77+
4578
return 0;
4679
}
4780

4881

4982
void uv__platform_loop_delete(uv_loop_t* loop) {
50-
uv__fsevents_loop_delete(loop);
83+
ngx_queue_t* item;
84+
uv__cf_loop_signal_t* s;
85+
86+
assert(loop->cf_loop != NULL);
87+
uv__cf_loop_signal(loop, NULL, NULL);
88+
uv_thread_join(&loop->cf_thread);
89+
90+
uv_sem_destroy(&loop->cf_sem);
91+
uv_mutex_destroy(&loop->cf_mutex);
92+
93+
/* Free any remaining data */
94+
while (!ngx_queue_empty(&loop->cf_signals)) {
95+
item = ngx_queue_head(&loop->cf_signals);
96+
97+
s = ngx_queue_data(item, uv__cf_loop_signal_t, member);
98+
99+
ngx_queue_remove(item);
100+
free(s);
101+
}
102+
}
103+
104+
105+
static void uv__cf_loop_runner(void* arg) {
106+
uv_loop_t* loop;
107+
108+
loop = arg;
109+
110+
/* Get thread's loop */
111+
ACCESS_ONCE(CFRunLoopRef, loop->cf_loop) = CFRunLoopGetCurrent();
112+
113+
CFRunLoopAddSource(loop->cf_loop,
114+
loop->cf_cb,
115+
kCFRunLoopDefaultMode);
116+
117+
uv_sem_post(&loop->cf_sem);
118+
119+
CFRunLoopRun();
120+
121+
CFRunLoopRemoveSource(loop->cf_loop,
122+
loop->cf_cb,
123+
kCFRunLoopDefaultMode);
124+
}
125+
126+
127+
static void uv__cf_loop_cb(void* arg) {
128+
uv_loop_t* loop;
129+
ngx_queue_t* item;
130+
ngx_queue_t split_head;
131+
uv__cf_loop_signal_t* s;
132+
133+
loop = arg;
134+
135+
uv_mutex_lock(&loop->cf_mutex);
136+
ngx_queue_init(&split_head);
137+
if (!ngx_queue_empty(&loop->cf_signals)) {
138+
ngx_queue_t* split_pos = ngx_queue_next(&loop->cf_signals);
139+
ngx_queue_split(&loop->cf_signals, split_pos, &split_head);
140+
}
141+
uv_mutex_unlock(&loop->cf_mutex);
142+
143+
while (!ngx_queue_empty(&split_head)) {
144+
item = ngx_queue_head(&split_head);
145+
146+
s = ngx_queue_data(item, uv__cf_loop_signal_t, member);
147+
148+
/* This was a termination signal */
149+
if (s->cb == NULL)
150+
CFRunLoopStop(loop->cf_loop);
151+
else
152+
s->cb(s->arg);
153+
154+
ngx_queue_remove(item);
155+
free(s);
156+
}
157+
}
158+
159+
160+
void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg) {
161+
uv__cf_loop_signal_t* item;
162+
163+
item = malloc(sizeof(*item));
164+
/* XXX: Fail */
165+
if (item == NULL)
166+
abort();
167+
168+
item->arg = arg;
169+
item->cb = cb;
170+
171+
uv_mutex_lock(&loop->cf_mutex);
172+
ngx_queue_insert_tail(&loop->cf_signals, &item->member);
173+
uv_mutex_unlock(&loop->cf_mutex);
174+
175+
assert(loop->cf_loop != NULL);
176+
CFRunLoopSourceSignal(loop->cf_cb);
177+
CFRunLoopWakeUp(loop->cf_loop);
51178
}
52179

53180

0 commit comments

Comments
 (0)