/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "uv.h"
#include "internal.h"

#if TARGET_OS_IPHONE || MAC_OS_X_VERSION_MAX_ALLOWED < 1070

/* iOS (currently) doesn't provide the FSEvents-API (nor CoreServices) */
/* macOS prior to 10.7 doesn't provide the full FSEvents API so use kqueue */

int uv__fsevents_init(uv_fs_event_t* handle) {
  return 0;
}


int uv__fsevents_close(uv_fs_event_t* handle) {
  return 0;
}


void uv__fsevents_loop_delete(uv_loop_t* loop) {
}

#else /* TARGET_OS_IPHONE */

#include <dlfcn.h>
#include <assert.h>
#include <stdlib.h>
#include <pthread.h>

#include <CoreFoundation/CFRunLoop.h>
#include <CoreServices/CoreServices.h>

/* These are macros to avoid "initializer element is not constant" errors
 * with old versions of gcc.
 */
#define kFSEventsModified (kFSEventStreamEventFlagItemFinderInfoMod |         \
                           kFSEventStreamEventFlagItemModified |              \
                           kFSEventStreamEventFlagItemInodeMetaMod |          \
                           kFSEventStreamEventFlagItemChangeOwner |           \
                           kFSEventStreamEventFlagItemXattrMod)

#define kFSEventsRenamed  (kFSEventStreamEventFlagItemCreated |               \
                           kFSEventStreamEventFlagItemRemoved |               \
                           kFSEventStreamEventFlagItemRenamed)

#define kFSEventsSystem   (kFSEventStreamEventFlagUserDropped |               \
                           kFSEventStreamEventFlagKernelDropped |             \
                           kFSEventStreamEventFlagEventIdsWrapped |           \
                           kFSEventStreamEventFlagHistoryDone |               \
                           kFSEventStreamEventFlagMount |                     \
                           kFSEventStreamEventFlagUnmount |                   \
                           kFSEventStreamEventFlagRootChanged)

typedef struct uv__fsevents_event_s uv__fsevents_event_t;
typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
typedef struct uv__cf_loop_state_s uv__cf_loop_state_t;

enum uv__cf_loop_signal_type_e {
  kUVCFLoopSignalRegular,
  kUVCFLoopSignalClosing
};
typedef enum uv__cf_loop_signal_type_e uv__cf_loop_signal_type_t;

struct uv__cf_loop_signal_s {
  QUEUE member;
  uv_fs_event_t* handle;
  uv__cf_loop_signal_type_t type;
};

struct uv__fsevents_event_s {
  QUEUE member;
  int events;
  char path[1];
};

struct uv__cf_loop_state_s {
  CFRunLoopRef loop;
  CFRunLoopSourceRef signal_source;
  int fsevent_need_reschedule;
  FSEventStreamRef fsevent_stream;
  uv_sem_t fsevent_sem;
  uv_mutex_t fsevent_mutex;
  void* fsevent_handles[2];
  unsigned int fsevent_handle_count;
};

/* Forward declarations */
static void uv__cf_loop_cb(void* arg);
static void* uv__cf_loop_runner(void* arg);
static int uv__cf_loop_signal(uv_loop_t* loop,
                              uv_fs_event_t* handle,
                              uv__cf_loop_signal_type_t type);

/* Lazy-loaded by uv__fsevents_global_init(). */
static CFArrayRef (*pCFArrayCreate)(CFAllocatorRef,
                                    const void**,
                                    CFIndex,
                                    const CFArrayCallBacks*);
static void (*pCFRelease)(CFTypeRef);
static void (*pCFRunLoopAddSource)(CFRunLoopRef,
                                   CFRunLoopSourceRef,
                                   CFStringRef);
static CFRunLoopRef (*pCFRunLoopGetCurrent)(void);
static void (*pCFRunLoopRemoveSource)(CFRunLoopRef,
                                      CFRunLoopSourceRef,
                                      CFStringRef);
static void (*pCFRunLoopRun)(void);
static CFRunLoopSourceRef (*pCFRunLoopSourceCreate)(CFAllocatorRef,
                                                    CFIndex,
                                                    CFRunLoopSourceContext*);
static void (*pCFRunLoopSourceSignal)(CFRunLoopSourceRef);
static void (*pCFRunLoopStop)(CFRunLoopRef);
static void (*pCFRunLoopWakeUp)(CFRunLoopRef);
static CFStringRef (*pCFStringCreateWithFileSystemRepresentation)(
    CFAllocatorRef,
    const char*);
static CFStringEncoding (*pCFStringGetSystemEncoding)(void);
static CFStringRef (*pkCFRunLoopDefaultMode);
static FSEventStreamRef (*pFSEventStreamCreate)(CFAllocatorRef,
                                                FSEventStreamCallback,
                                                FSEventStreamContext*,
                                                CFArrayRef,
                                                FSEventStreamEventId,
                                                CFTimeInterval,
                                                FSEventStreamCreateFlags);
static void (*pFSEventStreamFlushSync)(FSEventStreamRef);
static void (*pFSEventStreamInvalidate)(FSEventStreamRef);
static void (*pFSEventStreamRelease)(FSEventStreamRef);
static void (*pFSEventStreamScheduleWithRunLoop)(FSEventStreamRef,
                                                 CFRunLoopRef,
                                                 CFStringRef);
static Boolean (*pFSEventStreamStart)(FSEventStreamRef);
static void (*pFSEventStreamStop)(FSEventStreamRef);

#define UV__FSEVENTS_PROCESS(handle, block)                                   \
    do {                                                                      \
      QUEUE events;                                                           \
      QUEUE* q;                                                               \
      uv__fsevents_event_t* event;                                            \
      int err;                                                                \
      uv_mutex_lock(&(handle)->cf_mutex);                                     \
      /* Split-off all events and empty original queue */                     \
      QUEUE_MOVE(&(handle)->cf_events, &events);                              \
      /* Get error (if any) and zero original one */                          \
      err = (handle)->cf_error;                                               \
      (handle)->cf_error = 0;                                                 \
      uv_mutex_unlock(&(handle)->cf_mutex);                                   \
      /* Loop through events, deallocating each after processing */           \
      while (!QUEUE_EMPTY(&events)) {                                         \
        q = QUEUE_HEAD(&events);                                              \
        event = QUEUE_DATA(q, uv__fsevents_event_t, member);                  \
        QUEUE_REMOVE(q);                                                      \
        /* NOTE: Checking uv__is_active() is required here, because handle    \
         * callback may close handle and invoking it after it will lead to    \
         * incorrect behaviour */                                             \
        if (!uv__is_closing((handle)) && uv__is_active((handle)))             \
          block                                                               \
        /* Free allocated data */                                             \
        uv__free(event);                                                      \
      }                                                                       \
      if (err != 0 && !uv__is_closing((handle)) && uv__is_active((handle)))   \
        (handle)->cb((handle), NULL, 0, err);                                 \
    } while (0)


/* Runs in UV loop's thread, when there're events to report to handle */
static void uv__fsevents_cb(uv_async_t* cb) {
  uv_fs_event_t* handle;

  handle = cb->data;

  UV__FSEVENTS_PROCESS(handle, {
    handle->cb(handle, event->path[0] ? event->path : NULL, event->events, 0);
  });
}


/* Runs in CF thread, pushed event into handle's event list */
static void uv__fsevents_push_event(uv_fs_event_t* handle,
                                    QUEUE* events,
                                    int err) {
  assert(events != NULL || err != 0);
  uv_mutex_lock(&handle->cf_mutex);

  /* Concatenate two queues */
  if (events != NULL)
    QUEUE_ADD(&handle->cf_events, events);

  /* Propagate error */
  if (err != 0)
    handle->cf_error = err;
  uv_mutex_unlock(&handle->cf_mutex);

  uv_async_send(handle->cf_cb);
}


/* Runs in CF thread, when there're events in FSEventStream */
static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
                                  void* info,
                                  size_t numEvents,
                                  void* eventPaths,
                                  const FSEventStreamEventFlags eventFlags[],
                                  const FSEventStreamEventId eventIds[]) {
  size_t i;
  int len;
  char** paths;
  char* path;
  char* pos;
  uv_fs_event_t* handle;
  QUEUE* q;
  uv_loop_t* loop;
  uv__cf_loop_state_t* state;
  uv__fsevents_event_t* event;
  FSEventStreamEventFlags flags;
  QUEUE head;

  loop = info;
  state = loop->cf_state;
  assert(state != NULL);
  paths = eventPaths;

  /* For each handle */
  uv_mutex_lock(&state->fsevent_mutex);
  QUEUE_FOREACH(q, &state->fsevent_handles) {
    handle = QUEUE_DATA(q, uv_fs_event_t, cf_member);
    QUEUE_INIT(&head);

    /* Process and filter out events */
    for (i = 0; i < numEvents; i++) {
      flags = eventFlags[i];

      /* Ignore system events */
      if (flags & kFSEventsSystem)
        continue;

      path = paths[i];
      len = strlen(path);

      if (handle->realpath_len == 0)
        continue; /* This should be unreachable */

      /* Filter out paths that are outside handle's request */
      if (len < handle->realpath_len)
        continue;

      if (handle->realpath_len != len &&
          path[handle->realpath_len] != '/')
        /* Make sure that realpath actually named a directory,
         * or that we matched the whole string */
        continue;

      if (memcmp(path, handle->realpath, handle->realpath_len) != 0)
        continue;

      if (!(handle->realpath_len == 1 && handle->realpath[0] == '/')) {
        /* Remove common prefix, unless the watched folder is "/" */
        path += handle->realpath_len;
        len -= handle->realpath_len;

        /* Ignore events with path equal to directory itself */
        if (len <= 1 && (flags & kFSEventStreamEventFlagItemIsDir))
          continue;

        if (len == 0) {
          /* Since we're using fsevents to watch the file itself,
           * realpath == path, and we now need to get the basename of the file back
           * (for commonality with other codepaths and platforms). */
          while (len < handle->realpath_len && path[-1] != '/') {
            path--;
            len++;
          }
          /* Created and Removed seem to be always set, but don't make sense */
          flags &= ~kFSEventsRenamed;
        } else {
          /* Skip forward slash */
          path++;
          len--;
        }
      }

      /* Do not emit events from subdirectories (without option set) */
      if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 && *path != '\0') {
        pos = strchr(path + 1, '/');
        if (pos != NULL)
          continue;
      }

      event = uv__malloc(sizeof(*event) + len);
      if (event == NULL)
        break;

      memset(event, 0, sizeof(*event));
      memcpy(event->path, path, len + 1);
      event->events = UV_RENAME;

      if (0 == (flags & kFSEventsRenamed)) {
        if (0 != (flags & kFSEventsModified) ||
            0 == (flags & kFSEventStreamEventFlagItemIsDir))
          event->events = UV_CHANGE;
      }

      QUEUE_INSERT_TAIL(&head, &event->member);
    }

    if (!QUEUE_EMPTY(&head))
      uv__fsevents_push_event(handle, &head, 0);
  }
  uv_mutex_unlock(&state->fsevent_mutex);
}


/* Runs in CF thread */
static int uv__fsevents_create_stream(uv_loop_t* loop, CFArrayRef paths) {
  uv__cf_loop_state_t* state;
  FSEventStreamContext ctx;
  FSEventStreamRef ref;
  CFAbsoluteTime latency;
  FSEventStreamCreateFlags flags;

  /* Initialize context */
  ctx.version = 0;
  ctx.info = loop;
  ctx.retain = NULL;
  ctx.release = NULL;
  ctx.copyDescription = NULL;

  latency = 0.05;

  /* Explanation of selected flags:
   * 1. NoDefer - without this flag, events that are happening continuously
   *    (i.e. each event is happening after time interval less than `latency`,
   *    counted from previous event), will be deferred and passed to callback
   *    once they'll either fill whole OS buffer, or when this continuous stream
   *    will stop (i.e. there'll be delay between events, bigger than
   *    `latency`).
   *    Specifying this flag will invoke callback after `latency` time passed
   *    since event.
   * 2. FileEvents - fire callback for file changes too (by default it is firing
   *    it only for directory changes).
   */
  flags = kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents;

  /*
   * NOTE: It might sound like a good idea to remember last seen StreamEventId,
   * but in reality one dir might have last StreamEventId less than, the other,
   * that is being watched now. Which will cause FSEventStream API to report
   * changes to files from the past.
   */
  ref = pFSEventStreamCreate(NULL,
                             &uv__fsevents_event_cb,
                             &ctx,
                             paths,
                             kFSEventStreamEventIdSinceNow,
                             latency,
                             flags);
  assert(ref != NULL);

  state = loop->cf_state;
  pFSEventStreamScheduleWithRunLoop(ref,
                                    state->loop,
                                    *pkCFRunLoopDefaultMode);
  if (!pFSEventStreamStart(ref)) {
    pFSEventStreamInvalidate(ref);
    pFSEventStreamRelease(ref);
    return UV_EMFILE;
  }

  state->fsevent_stream = ref;
  return 0;
}


/* Runs in CF thread */
static void uv__fsevents_destroy_stream(uv_loop_t* loop) {
  uv__cf_loop_state_t* state;

  state = loop->cf_state;

  if (state->fsevent_stream == NULL)
    return;

  /* Stop emitting events */
  pFSEventStreamStop(state->fsevent_stream);

  /* Release stream */
  pFSEventStreamInvalidate(state->fsevent_stream);
  pFSEventStreamRelease(state->fsevent_stream);
  state->fsevent_stream = NULL;
}


/* Runs in CF thread, when there're new fsevent handles to add to stream */
static void uv__fsevents_reschedule(uv_fs_event_t* handle,
                                    uv__cf_loop_signal_type_t type) {
  uv__cf_loop_state_t* state;
  QUEUE* q;
  uv_fs_event_t* curr;
  CFArrayRef cf_paths;
  CFStringRef* paths;
  unsigned int i;
  int err;
  unsigned int path_count;

  state = handle->loop->cf_state;
  paths = NULL;
  cf_paths = NULL;
  err = 0;
  /* NOTE: `i` is used in deallocation loop below */
  i = 0;

  /* Optimization to prevent O(n^2) time spent when starting to watch
   * many files simultaneously
   */
  uv_mutex_lock(&state->fsevent_mutex);
  if (state->fsevent_need_reschedule == 0) {
    uv_mutex_unlock(&state->fsevent_mutex);
    goto final;
  }
  state->fsevent_need_reschedule = 0;
  uv_mutex_unlock(&state->fsevent_mutex);

  /* Destroy previous FSEventStream */
  uv__fsevents_destroy_stream(handle->loop);

  /* Any failure below will be a memory failure */
  err = UV_ENOMEM;

  /* Create list of all watched paths */
  uv_mutex_lock(&state->fsevent_mutex);
  path_count = state->fsevent_handle_count;
  if (path_count != 0) {
    paths = uv__malloc(sizeof(*paths) * path_count);
    if (paths == NULL) {
      uv_mutex_unlock(&state->fsevent_mutex);
      goto final;
    }

    q = &state->fsevent_handles;
    for (; i < path_count; i++) {
      q = QUEUE_NEXT(q);
      assert(q != &state->fsevent_handles);
      curr = QUEUE_DATA(q, uv_fs_event_t, cf_member);

      assert(curr->realpath != NULL);
      paths[i] =
          pCFStringCreateWithFileSystemRepresentation(NULL, curr->realpath);
      if (paths[i] == NULL) {
        uv_mutex_unlock(&state->fsevent_mutex);
        goto final;
      }
    }
  }
  uv_mutex_unlock(&state->fsevent_mutex);
  err = 0;

  if (path_count != 0) {
    /* Create new FSEventStream */
    cf_paths = pCFArrayCreate(NULL, (const void**) paths, path_count, NULL);
    if (cf_paths == NULL) {
      err = UV_ENOMEM;
      goto final;
    }
    err = uv__fsevents_create_stream(handle->loop, cf_paths);
  }

final:
  /* Deallocate all paths in case of failure */
  if (err != 0) {
    if (cf_paths == NULL) {
      while (i != 0)
        pCFRelease(paths[--i]);
      uv__free(paths);
    } else {
      /* CFArray takes ownership of both strings and original C-array */
      pCFRelease(cf_paths);
    }

    /* Broadcast error to all handles */
    uv_mutex_lock(&state->fsevent_mutex);
    QUEUE_FOREACH(q, &state->fsevent_handles) {
      curr = QUEUE_DATA(q, uv_fs_event_t, cf_member);
      uv__fsevents_push_event(curr, NULL, err);
    }
    uv_mutex_unlock(&state->fsevent_mutex);
  }

  /*
   * Main thread will block until the removal of handle from the list,
   * we must tell it when we're ready.
   *
   * NOTE: This is coupled with `uv_sem_wait()` in `uv__fsevents_close`
   */
  if (type == kUVCFLoopSignalClosing)
    uv_sem_post(&state->fsevent_sem);
}


static int uv__fsevents_global_init(void) {
  static pthread_mutex_t global_init_mutex = PTHREAD_MUTEX_INITIALIZER;
  static void* core_foundation_handle;
  static void* core_services_handle;
  int err;

  err = 0;
  pthread_mutex_lock(&global_init_mutex);
  if (core_foundation_handle != NULL)
    goto out;

  /* The libraries are never unloaded because we currently don't have a good
   * mechanism for keeping a reference count. It's unlikely to be an issue
   * but if it ever becomes one, we can turn the dynamic library handles into
   * per-event loop properties and have the dynamic linker keep track for us.
   */
  err = UV_ENOSYS;
  core_foundation_handle = dlopen("/System/Library/Frameworks/"
                                  "CoreFoundation.framework/"
                                  "Versions/A/CoreFoundation",
                                  RTLD_LAZY | RTLD_LOCAL);
  if (core_foundation_handle == NULL)
    goto out;

  core_services_handle = dlopen("/System/Library/Frameworks/"
                                "CoreServices.framework/"
                                "Versions/A/CoreServices",
                                RTLD_LAZY | RTLD_LOCAL);
  if (core_services_handle == NULL)
    goto out;

  err = UV_ENOENT;
#define V(handle, symbol)                                                     \
  do {                                                                        \
    *(void **)(&p ## symbol) = dlsym((handle), #symbol);                      \
    if (p ## symbol == NULL)                                                  \
      goto out;                                                               \
  }                                                                           \
  while (0)
  V(core_foundation_handle, CFArrayCreate);
  V(core_foundation_handle, CFRelease);
  V(core_foundation_handle, CFRunLoopAddSource);
  V(core_foundation_handle, CFRunLoopGetCurrent);
  V(core_foundation_handle, CFRunLoopRemoveSource);
  V(core_foundation_handle, CFRunLoopRun);
  V(core_foundation_handle, CFRunLoopSourceCreate);
  V(core_foundation_handle, CFRunLoopSourceSignal);
  V(core_foundation_handle, CFRunLoopStop);
  V(core_foundation_handle, CFRunLoopWakeUp);
  V(core_foundation_handle, CFStringCreateWithFileSystemRepresentation);
  V(core_foundation_handle, CFStringGetSystemEncoding);
  V(core_foundation_handle, kCFRunLoopDefaultMode);
  V(core_services_handle, FSEventStreamCreate);
  V(core_services_handle, FSEventStreamFlushSync);
  V(core_services_handle, FSEventStreamInvalidate);
  V(core_services_handle, FSEventStreamRelease);
  V(core_services_handle, FSEventStreamScheduleWithRunLoop);
  V(core_services_handle, FSEventStreamStart);
  V(core_services_handle, FSEventStreamStop);
#undef V
  err = 0;

out:
  if (err && core_services_handle != NULL) {
    dlclose(core_services_handle);
    core_services_handle = NULL;
  }

  if (err && core_foundation_handle != NULL) {
    dlclose(core_foundation_handle);
    core_foundation_handle = NULL;
  }

  pthread_mutex_unlock(&global_init_mutex);
  return err;
}


/* Runs in UV loop */
static int uv__fsevents_loop_init(uv_loop_t* loop) {
  CFRunLoopSourceContext ctx;
  uv__cf_loop_state_t* state;
  pthread_attr_t attr_storage;
  pthread_attr_t* attr;
  int err;

  if (loop->cf_state != NULL)
    return 0;

  err = uv__fsevents_global_init();
  if (err)
    return err;

  state = uv__calloc(1, sizeof(*state));
  if (state == NULL)
    return UV_ENOMEM;

  err = uv_mutex_init(&loop->cf_mutex);
  if (err)
    goto fail_mutex_init;

  err = uv_sem_init(&loop->cf_sem, 0);
  if (err)
    goto fail_sem_init;

  QUEUE_INIT(&loop->cf_signals);

  err = uv_sem_init(&state->fsevent_sem, 0);
  if (err)
    goto fail_fsevent_sem_init;

  err = uv_mutex_init(&state->fsevent_mutex);
  if (err)
    goto fail_fsevent_mutex_init;

  QUEUE_INIT(&state->fsevent_handles);
  state->fsevent_need_reschedule = 0;
  state->fsevent_handle_count = 0;

  memset(&ctx, 0, sizeof(ctx));
  ctx.info = loop;
  ctx.perform = uv__cf_loop_cb;
  state->signal_source = pCFRunLoopSourceCreate(NULL, 0, &ctx);
  if (state->signal_source == NULL) {
    err = UV_ENOMEM;
    goto fail_signal_source_create;
  }

  /* In the unlikely event that pthread_attr_init() fails, create the thread
   * with the default stack size. We'll use a little more address space but
   * that in itself is not a fatal error.
   */
  attr = &attr_storage;
  if (pthread_attr_init(attr))
    attr = NULL;

  if (attr != NULL)
    if (pthread_attr_setstacksize(attr, 4 * PTHREAD_STACK_MIN))
      abort();

  loop->cf_state = state;

  /* uv_thread_t is an alias for pthread_t. */
  err = UV__ERR(pthread_create(&loop->cf_thread, attr, uv__cf_loop_runner, loop));

  if (attr != NULL)
    pthread_attr_destroy(attr);

  if (err)
    goto fail_thread_create;

  /* Synchronize threads */
  uv_sem_wait(&loop->cf_sem);
  return 0;

fail_thread_create:
  loop->cf_state = NULL;

fail_signal_source_create:
  uv_mutex_destroy(&state->fsevent_mutex);

fail_fsevent_mutex_init:
  uv_sem_destroy(&state->fsevent_sem);

fail_fsevent_sem_init:
  uv_sem_destroy(&loop->cf_sem);

fail_sem_init:
  uv_mutex_destroy(&loop->cf_mutex);

fail_mutex_init:
  uv__free(state);
  return err;
}


/* Runs in UV loop */
void uv__fsevents_loop_delete(uv_loop_t* loop) {
  uv__cf_loop_signal_t* s;
  uv__cf_loop_state_t* state;
  QUEUE* q;

  if (loop->cf_state == NULL)
    return;

  if (uv__cf_loop_signal(loop, NULL, kUVCFLoopSignalRegular) != 0)
    abort();

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

  /* Free any remaining data */
  while (!QUEUE_EMPTY(&loop->cf_signals)) {
    q = QUEUE_HEAD(&loop->cf_signals);
    s = QUEUE_DATA(q, uv__cf_loop_signal_t, member);
    QUEUE_REMOVE(q);
    uv__free(s);
  }

  /* Destroy state */
  state = loop->cf_state;
  uv_sem_destroy(&state->fsevent_sem);
  uv_mutex_destroy(&state->fsevent_mutex);
  pCFRelease(state->signal_source);
  uv__free(state);
  loop->cf_state = NULL;
}


/* Runs in CF thread. This is the CF loop's body */
static void* uv__cf_loop_runner(void* arg) {
  uv_loop_t* loop;
  uv__cf_loop_state_t* state;

  loop = arg;
  state = loop->cf_state;
  state->loop = pCFRunLoopGetCurrent();

  pCFRunLoopAddSource(state->loop,
                      state->signal_source,
                      *pkCFRunLoopDefaultMode);

  uv_sem_post(&loop->cf_sem);

  pCFRunLoopRun();
  pCFRunLoopRemoveSource(state->loop,
                         state->signal_source,
                         *pkCFRunLoopDefaultMode);

  return NULL;
}


/* Runs in CF thread, executed after `uv__cf_loop_signal()` */
static void uv__cf_loop_cb(void* arg) {
  uv_loop_t* loop;
  uv__cf_loop_state_t* state;
  QUEUE* item;
  QUEUE split_head;
  uv__cf_loop_signal_t* s;

  loop = arg;
  state = loop->cf_state;

  uv_mutex_lock(&loop->cf_mutex);
  QUEUE_MOVE(&loop->cf_signals, &split_head);
  uv_mutex_unlock(&loop->cf_mutex);

  while (!QUEUE_EMPTY(&split_head)) {
    item = QUEUE_HEAD(&split_head);
    QUEUE_REMOVE(item);

    s = QUEUE_DATA(item, uv__cf_loop_signal_t, member);

    /* This was a termination signal */
    if (s->handle == NULL)
      pCFRunLoopStop(state->loop);
    else
      uv__fsevents_reschedule(s->handle, s->type);

    uv__free(s);
  }
}


/* Runs in UV loop to notify CF thread */
int uv__cf_loop_signal(uv_loop_t* loop,
                       uv_fs_event_t* handle,
                       uv__cf_loop_signal_type_t type) {
  uv__cf_loop_signal_t* item;
  uv__cf_loop_state_t* state;

  item = uv__malloc(sizeof(*item));
  if (item == NULL)
    return UV_ENOMEM;

  item->handle = handle;
  item->type = type;

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

  state = loop->cf_state;
  assert(state != NULL);
  pCFRunLoopSourceSignal(state->signal_source);
  pCFRunLoopWakeUp(state->loop);

  return 0;
}


/* Runs in UV loop to initialize handle */
int uv__fsevents_init(uv_fs_event_t* handle) {
  int err;
  uv__cf_loop_state_t* state;

  err = uv__fsevents_loop_init(handle->loop);
  if (err)
    return err;

  /* Get absolute path to file */
  handle->realpath = realpath(handle->path, NULL);
  if (handle->realpath == NULL)
    return UV__ERR(errno);
  handle->realpath_len = strlen(handle->realpath);

  /* Initialize event queue */
  QUEUE_INIT(&handle->cf_events);
  handle->cf_error = 0;

  /*
   * Events will occur in other thread.
   * Initialize callback for getting them back into event loop's thread
   */
  handle->cf_cb = uv__malloc(sizeof(*handle->cf_cb));
  if (handle->cf_cb == NULL) {
    err = UV_ENOMEM;
    goto fail_cf_cb_malloc;
  }

  handle->cf_cb->data = handle;
  uv_async_init(handle->loop, handle->cf_cb, uv__fsevents_cb);
  handle->cf_cb->flags |= UV_HANDLE_INTERNAL;
  uv_unref((uv_handle_t*) handle->cf_cb);

  err = uv_mutex_init(&handle->cf_mutex);
  if (err)
    goto fail_cf_mutex_init;

  /* Insert handle into the list */
  state = handle->loop->cf_state;
  uv_mutex_lock(&state->fsevent_mutex);
  QUEUE_INSERT_TAIL(&state->fsevent_handles, &handle->cf_member);
  state->fsevent_handle_count++;
  state->fsevent_need_reschedule = 1;
  uv_mutex_unlock(&state->fsevent_mutex);

  /* Reschedule FSEventStream */
  assert(handle != NULL);
  err = uv__cf_loop_signal(handle->loop, handle, kUVCFLoopSignalRegular);
  if (err)
    goto fail_loop_signal;

  return 0;

fail_loop_signal:
  uv_mutex_destroy(&handle->cf_mutex);

fail_cf_mutex_init:
  uv__free(handle->cf_cb);
  handle->cf_cb = NULL;

fail_cf_cb_malloc:
  uv__free(handle->realpath);
  handle->realpath = NULL;
  handle->realpath_len = 0;

  return err;
}


/* Runs in UV loop to de-initialize handle */
int uv__fsevents_close(uv_fs_event_t* handle) {
  int err;
  uv__cf_loop_state_t* state;

  if (handle->cf_cb == NULL)
    return UV_EINVAL;

  /* Remove handle from  the list */
  state = handle->loop->cf_state;
  uv_mutex_lock(&state->fsevent_mutex);
  QUEUE_REMOVE(&handle->cf_member);
  state->fsevent_handle_count--;
  state->fsevent_need_reschedule = 1;
  uv_mutex_unlock(&state->fsevent_mutex);

  /* Reschedule FSEventStream */
  assert(handle != NULL);
  err = uv__cf_loop_signal(handle->loop, handle, kUVCFLoopSignalClosing);
  if (err)
    return UV__ERR(err);

  /* Wait for deinitialization */
  uv_sem_wait(&state->fsevent_sem);

  uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) uv__free);
  handle->cf_cb = NULL;

  /* Free data in queue */
  UV__FSEVENTS_PROCESS(handle, {
    /* NOP */
  });

  uv_mutex_destroy(&handle->cf_mutex);
  uv__free(handle->realpath);
  handle->realpath = NULL;
  handle->realpath_len = 0;

  return 0;
}

#endif /* TARGET_OS_IPHONE */
