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

Fsevents backport #896

Merged
merged 3 commits into from
Aug 22, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions include/uv-private/uv-darwin.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@

#define UV_PLATFORM_LOOP_FIELDS \
uv_thread_t cf_thread; \
void* cf_cb; \
void* cf_loop; \
void* _cf_reserved; \
void* cf_state; \
uv_mutex_t cf_mutex; \
uv_sem_t cf_sem; \
ngx_queue_t cf_signals; \
Expand All @@ -47,10 +47,10 @@
char* realpath; \
int realpath_len; \
int cf_flags; \
void* cf_eventstream; \
void* cf_event; \
uv_async_t* cf_cb; \
ngx_queue_t cf_events; \
uv_sem_t cf_sem; \
ngx_queue_t cf_member; \
uv_sem_t _cf_reserved; \
uv_mutex_t cf_mutex; \

#define UV_STREAM_PRIVATE_PLATFORM_FIELDS \
Expand Down
131 changes: 2 additions & 129 deletions src/unix/darwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,153 +28,26 @@
#include <ifaddrs.h>
#include <net/if.h>

#include <CoreFoundation/CFRunLoop.h>

#include <mach/mach.h>
#include <mach/mach_time.h>
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
#include <sys/resource.h>
#include <sys/sysctl.h>
#include <unistd.h> /* sysconf */

/* Forward declarations */
static void uv__cf_loop_runner(void* arg);
static void uv__cf_loop_cb(void* arg);

typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
struct uv__cf_loop_signal_s {
void* arg;
cf_loop_signal_cb cb;
ngx_queue_t member;
};


int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
CFRunLoopSourceContext ctx;
int r;
loop->cf_state = NULL;

if (uv__kqueue_init(loop))
return -1;

loop->cf_loop = NULL;
if ((r = uv_mutex_init(&loop->cf_mutex)))
return r;
if ((r = uv_sem_init(&loop->cf_sem, 0)))
return r;
ngx_queue_init(&loop->cf_signals);

memset(&ctx, 0, sizeof(ctx));
ctx.info = loop;
ctx.perform = uv__cf_loop_cb;
loop->cf_cb = CFRunLoopSourceCreate(NULL, 0, &ctx);

if ((r = uv_thread_create(&loop->cf_thread, uv__cf_loop_runner, loop)))
return r;

/* Synchronize threads */
uv_sem_wait(&loop->cf_sem);
assert(ACCESS_ONCE(CFRunLoopRef, loop->cf_loop) != NULL);

return 0;
}


void uv__platform_loop_delete(uv_loop_t* loop) {
ngx_queue_t* item;
uv__cf_loop_signal_t* s;

assert(loop->cf_loop != NULL);
uv__cf_loop_signal(loop, NULL, NULL);
uv_thread_join(&loop->cf_thread);

uv_sem_destroy(&loop->cf_sem);
uv_mutex_destroy(&loop->cf_mutex);

/* Free any remaining data */
while (!ngx_queue_empty(&loop->cf_signals)) {
item = ngx_queue_head(&loop->cf_signals);

s = ngx_queue_data(item, uv__cf_loop_signal_t, member);

ngx_queue_remove(item);
free(s);
}
}


static void uv__cf_loop_runner(void* arg) {
uv_loop_t* loop;

loop = arg;

/* Get thread's loop */
ACCESS_ONCE(CFRunLoopRef, loop->cf_loop) = CFRunLoopGetCurrent();

CFRunLoopAddSource(loop->cf_loop,
loop->cf_cb,
kCFRunLoopDefaultMode);

uv_sem_post(&loop->cf_sem);

CFRunLoopRun();

CFRunLoopRemoveSource(loop->cf_loop,
loop->cf_cb,
kCFRunLoopDefaultMode);
}


static void uv__cf_loop_cb(void* arg) {
uv_loop_t* loop;
ngx_queue_t* item;
ngx_queue_t split_head;
uv__cf_loop_signal_t* s;

loop = arg;

uv_mutex_lock(&loop->cf_mutex);
ngx_queue_init(&split_head);
if (!ngx_queue_empty(&loop->cf_signals)) {
ngx_queue_t* split_pos = ngx_queue_next(&loop->cf_signals);
ngx_queue_split(&loop->cf_signals, split_pos, &split_head);
}
uv_mutex_unlock(&loop->cf_mutex);

while (!ngx_queue_empty(&split_head)) {
item = ngx_queue_head(&split_head);

s = ngx_queue_data(item, uv__cf_loop_signal_t, member);

/* This was a termination signal */
if (s->cb == NULL)
CFRunLoopStop(loop->cf_loop);
else
s->cb(s->arg);

ngx_queue_remove(item);
free(s);
}
}


void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg) {
uv__cf_loop_signal_t* item;

item = malloc(sizeof(*item));
/* XXX: Fail */
if (item == NULL)
abort();

item->arg = arg;
item->cb = cb;

uv_mutex_lock(&loop->cf_mutex);
ngx_queue_insert_tail(&loop->cf_signals, &item->member);
uv_mutex_unlock(&loop->cf_mutex);

assert(loop->cf_loop != NULL);
CFRunLoopSourceSignal(loop->cf_cb);
CFRunLoopWakeUp(loop->cf_loop);
uv__fsevents_loop_delete(loop);
}


Expand Down
Loading