Alien-uv

 view release on metacpan or  search on metacpan

libuv/src/unix/fsevents.c  view on Meta::CPAN

            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;
}



( run in 0.748 second using v1.01-cache-2.11-cpan-0bd6704ced7 )