thread.cc 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /*
  2. ** © 2014 by Philipp Dunkel <pip@pipobscure.com>
  3. ** Licensed under MIT License.
  4. */
  5. // constants from https://developer.apple.com/library/mac/documentation/Darwin/Reference/FSEvents_Ref/index.html#//apple_ref/doc/constant_group/FSEventStreamCreateFlags
  6. #ifndef kFSEventStreamCreateFlagNone
  7. #define kFSEventStreamCreateFlagNone 0x00000000
  8. #endif
  9. #ifndef kFSEventStreamCreateFlagUseCFTypes
  10. #define kFSEventStreamCreateFlagUseCFTypes 0x00000001
  11. #endif
  12. #ifndef kFSEventStreamCreateFlagNoDefer
  13. #define kFSEventStreamCreateFlagNoDefer 0x00000002
  14. #endif
  15. #ifndef kFSEventStreamCreateFlagWatchRoot
  16. #define kFSEventStreamCreateFlagWatchRoot 0x00000004
  17. #endif
  18. #ifndef kFSEventStreamCreateFlagIgnoreSelf
  19. #define kFSEventStreamCreateFlagIgnoreSelf 0x00000008
  20. #endif
  21. #ifndef kFSEventStreamCreateFlagFileEvents
  22. #define kFSEventStreamCreateFlagFileEvents 0x00000010
  23. #endif
  24. void FSEvents::threadStart() {
  25. if (threadloop) return;
  26. if (uv_thread_create(&thread, &FSEvents::threadRun, this)) abort();
  27. }
  28. void HandleStreamEvents(ConstFSEventStreamRef stream, void *ctx, size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) {
  29. FSEvents * fse = (FSEvents *)ctx;
  30. size_t idx;
  31. uv_mutex_lock(&fse->mutex);
  32. for (idx=0; idx < numEvents; idx++) {
  33. fse_event *event = new fse_event(
  34. (CFStringRef)CFArrayGetValueAtIndex((CFArrayRef)eventPaths, idx),
  35. eventFlags[idx],
  36. eventIds[idx]
  37. );
  38. fse->events.push_back(event);
  39. }
  40. fse->asyncTrigger();
  41. uv_mutex_unlock(&fse->mutex);
  42. }
  43. void FSEvents::threadRun(void *ctx) {
  44. FSEvents *fse = (FSEvents*)ctx;
  45. FSEventStreamContext context = { 0, ctx, NULL, NULL, NULL };
  46. fse->threadloop = CFRunLoopGetCurrent();
  47. FSEventStreamRef stream = FSEventStreamCreate(NULL, &HandleStreamEvents, &context, fse->paths, kFSEventStreamEventIdSinceNow, (CFAbsoluteTime) 0.1, kFSEventStreamCreateFlagNone | kFSEventStreamCreateFlagWatchRoot | kFSEventStreamCreateFlagFileEvents | kFSEventStreamCreateFlagUseCFTypes);
  48. FSEventStreamScheduleWithRunLoop(stream, fse->threadloop, kCFRunLoopDefaultMode);
  49. FSEventStreamStart(stream);
  50. CFRunLoopRun();
  51. FSEventStreamStop(stream);
  52. FSEventStreamUnscheduleFromRunLoop(stream, fse->threadloop, kCFRunLoopDefaultMode);
  53. FSEventStreamInvalidate(stream);
  54. FSEventStreamRelease(stream);
  55. fse->threadloop = NULL;
  56. }
  57. void FSEvents::threadStop() {
  58. if (!threadloop) return;
  59. CFRunLoopStop(threadloop);
  60. if (uv_thread_join(&thread)) abort();
  61. }