diff options
Diffstat (limited to 'node_modules/fsevents/src')
| -rw-r--r-- | node_modules/fsevents/src/async.cc | 43 | ||||
| -rw-r--r-- | node_modules/fsevents/src/constants.cc | 110 | ||||
| -rw-r--r-- | node_modules/fsevents/src/locking.cc | 27 | ||||
| -rw-r--r-- | node_modules/fsevents/src/methods.cc | 44 | ||||
| -rw-r--r-- | node_modules/fsevents/src/storage.cc | 27 | ||||
| -rw-r--r-- | node_modules/fsevents/src/thread.cc | 72 |
6 files changed, 323 insertions, 0 deletions
diff --git a/node_modules/fsevents/src/async.cc b/node_modules/fsevents/src/async.cc new file mode 100644 index 00000000..d5129940 --- /dev/null +++ b/node_modules/fsevents/src/async.cc @@ -0,0 +1,43 @@ +/* +** © 2014 by Philipp Dunkel <pip@pipobscure.com> +** Licensed under MIT License. +*/ + + +void async_propagate(uv_async_t *async) { + if (!async->data) return; + FSEvents *fse = (FSEvents *)async->data; + CFIndex idx, cnt; + fse_event *event; + char pathbuf[1024]; + const char *pathptr = NULL; + fse->lock(); + cnt = fse->events.size(); + for (idx=0; idx<cnt; idx++) { + event = fse->events.at(idx); + if (event == NULL) continue; + pathptr = CFStringGetCStringPtr(event->path, kCFStringEncodingUTF8); + if (!pathptr) CFStringGetCString(event->path, pathbuf, 1024, kCFStringEncodingUTF8); + fse->emitEvent(pathptr ? pathptr : pathbuf, event->flags, event->id); + delete event; + } + if (cnt>0) fse->events.clear(); + fse->unlock(); +} + +void FSEvents::asyncStart() { + if (async.data == this) return; + async.data = this; + uv_async_init(uv_default_loop(), &async, (uv_async_cb) async_propagate); +} + +void FSEvents::asyncTrigger() { + if (async.data != this) return; + uv_async_send(&async); +} + +void FSEvents::asyncStop() { + if (async.data != this) return; + async.data = NULL; + uv_close((uv_handle_t *) &async, NULL); +} diff --git a/node_modules/fsevents/src/constants.cc b/node_modules/fsevents/src/constants.cc new file mode 100644 index 00000000..fbd61ee9 --- /dev/null +++ b/node_modules/fsevents/src/constants.cc @@ -0,0 +1,110 @@ +/* +** © 2014 by Philipp Dunkel <pip@pipobscure.com> +** Licensed under MIT License. +*/ + +// constants from https://developer.apple.com/library/mac/documentation/Darwin/Reference/FSEvents_Ref/index.html#//apple_ref/doc/constant_group/FSEventStreamEventFlags +#ifndef kFSEventStreamEventFlagNone +#define kFSEventStreamEventFlagNone 0x00000000 +#endif + +#ifndef kFSEventStreamEventFlagMustScanSubDirs +#define kFSEventStreamEventFlagMustScanSubDirs 0x00000001 +#endif + +#ifndef kFSEventStreamEventFlagUserDropped +#define kFSEventStreamEventFlagUserDropped 0x00000002 +#endif + +#ifndef kFSEventStreamEventFlagKernelDropped +#define kFSEventStreamEventFlagKernelDropped 0x00000004 +#endif + +#ifndef kFSEventStreamEventFlagEventIdsWrapped +#define kFSEventStreamEventFlagEventIdsWrapped 0x00000008 +#endif + +#ifndef kFSEventStreamEventFlagHistoryDone +#define kFSEventStreamEventFlagHistoryDone 0x00000010 +#endif + +#ifndef kFSEventStreamEventFlagRootChanged +#define kFSEventStreamEventFlagRootChanged 0x00000020 +#endif + +#ifndef kFSEventStreamEventFlagMount +#define kFSEventStreamEventFlagMount 0x00000040 +#endif + +#ifndef kFSEventStreamEventFlagUnmount +#define kFSEventStreamEventFlagUnmount 0x00000080 +#endif + +#ifndef kFSEventStreamEventFlagItemCreated +#define kFSEventStreamEventFlagItemCreated 0x00000100 +#endif + +#ifndef kFSEventStreamEventFlagItemRemoved +#define kFSEventStreamEventFlagItemRemoved 0x00000200 +#endif + +#ifndef kFSEventStreamEventFlagItemInodeMetaMod +#define kFSEventStreamEventFlagItemInodeMetaMod 0x00000400 +#endif + +#ifndef kFSEventStreamEventFlagItemRenamed +#define kFSEventStreamEventFlagItemRenamed 0x00000800 +#endif + +#ifndef kFSEventStreamEventFlagItemModified +#define kFSEventStreamEventFlagItemModified 0x00001000 +#endif + +#ifndef kFSEventStreamEventFlagItemFinderInfoMod +#define kFSEventStreamEventFlagItemFinderInfoMod 0x00002000 +#endif + +#ifndef kFSEventStreamEventFlagItemChangeOwner +#define kFSEventStreamEventFlagItemChangeOwner 0x00004000 +#endif + +#ifndef kFSEventStreamEventFlagItemXattrMod +#define kFSEventStreamEventFlagItemXattrMod 0x00008000 +#endif + +#ifndef kFSEventStreamEventFlagItemIsFile +#define kFSEventStreamEventFlagItemIsFile 0x00010000 +#endif + +#ifndef kFSEventStreamEventFlagItemIsDir +#define kFSEventStreamEventFlagItemIsDir 0x00020000 +#endif + +#ifndef kFSEventStreamEventFlagItemIsSymlink +#define kFSEventStreamEventFlagItemIsSymlink 0x00040000 +#endif + +static v8::Local<v8::Object> Constants() { + v8::Local<v8::Object> object = Nan::New<v8::Object>(); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagNone").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagNone)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagMustScanSubDirs").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagMustScanSubDirs)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagUserDropped").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagUserDropped)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagKernelDropped").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagKernelDropped)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagEventIdsWrapped").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagEventIdsWrapped)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagHistoryDone").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagHistoryDone)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagRootChanged").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagRootChanged)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagMount").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagMount)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagUnmount").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagUnmount)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagItemCreated").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagItemCreated)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagItemRemoved").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagItemRemoved)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagItemInodeMetaMod").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagItemInodeMetaMod)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagItemRenamed").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagItemRenamed)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagItemModified").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagItemModified)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagItemFinderInfoMod").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagItemFinderInfoMod)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagItemChangeOwner").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagItemChangeOwner)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagItemXattrMod").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagItemXattrMod)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagItemIsFile").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagItemIsFile)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagItemIsDir").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagItemIsDir)); + object->Set(Nan::New<v8::String>("kFSEventStreamEventFlagItemIsSymlink").ToLocalChecked(), Nan::New<v8::Integer>(kFSEventStreamEventFlagItemIsSymlink)); + return object; +} diff --git a/node_modules/fsevents/src/locking.cc b/node_modules/fsevents/src/locking.cc new file mode 100644 index 00000000..27120802 --- /dev/null +++ b/node_modules/fsevents/src/locking.cc @@ -0,0 +1,27 @@ +/* +** © 2014 by Philipp Dunkel <pip@pipobscure.com> +** Licensed under MIT License. +*/ + +void FSEvents::lockingStart() { + if (lockStarted) return; + lockStarted = true; + pthread_mutex_init(&lockmutex, NULL); +} + +void FSEvents::lock() { + if (!lockStarted) return; + pthread_mutex_lock(&lockmutex); +} + +void FSEvents::unlock() { + if (!lockStarted) return; + pthread_mutex_unlock(&lockmutex); +} + +void FSEvents::lockingStop() { + if (!lockStarted) return; + lockStarted = false; + + pthread_mutex_destroy(&lockmutex); +} diff --git a/node_modules/fsevents/src/methods.cc b/node_modules/fsevents/src/methods.cc new file mode 100644 index 00000000..a6d14888 --- /dev/null +++ b/node_modules/fsevents/src/methods.cc @@ -0,0 +1,44 @@ +/* +** © 2014 by Philipp Dunkel <pip@pipobscure.com> +** Licensed under MIT License. +*/ + +void FSEvents::emitEvent(const char *path, UInt32 flags, UInt64 id) { + Nan::HandleScope handle_scope; + v8::Local<v8::Object> object = handle(); + v8::Local<v8::Value> key = Nan::New<v8::String>("handler").ToLocalChecked(); + Nan::Callback handler(Nan::To<v8::Function>(Nan::Get(object, key).ToLocalChecked()).ToLocalChecked()); + v8::Local<v8::Value> argv[] = { + Nan::New<v8::String>(path).ToLocalChecked(), + Nan::New<v8::Number>(flags), + Nan::New<v8::Number>(id) + }; + handler.Call(3, argv, &async_resource); +} + +NAN_METHOD(FSEvents::New) { + Nan::Utf8String path(info[0]); + + FSEvents *fse = new FSEvents(*path); + fse->Wrap(info.This()); + Nan::Set(info.This(), Nan::New<v8::String>("handler").ToLocalChecked(), info[1]); + + info.GetReturnValue().Set(info.This()); +} + +NAN_METHOD(FSEvents::Stop) { + FSEvents* fse = Nan::ObjectWrap::Unwrap<FSEvents>(info.This()); + + fse->threadStop(); + fse->asyncStop(); + + info.GetReturnValue().Set(info.This()); +} + +NAN_METHOD(FSEvents::Start) { + FSEvents* fse = Nan::ObjectWrap::Unwrap<FSEvents>(info.This()); + fse->asyncStart(); + fse->threadStart(); + + info.GetReturnValue().Set(info.This()); +} diff --git a/node_modules/fsevents/src/storage.cc b/node_modules/fsevents/src/storage.cc new file mode 100644 index 00000000..9dc55881 --- /dev/null +++ b/node_modules/fsevents/src/storage.cc @@ -0,0 +1,27 @@ +/* + ** © 2014 by Philipp Dunkel <pip@pipobscure.com> + ** Licensed under MIT License. + */ + +struct fse_event { + UInt64 id; + UInt32 flags; + CFStringRef path; + + fse_event(CFStringRef eventPath, UInt32 eventFlag, UInt64 eventId) { + this->path = eventPath; + this->flags = eventFlag; + this->id = eventId; + if (this->path != NULL) + CFRetain(this->path); + } + + ~fse_event() { + if (this->path != NULL) + CFRelease(this->path); + } + +private: + fse_event(const fse_event&); + void operator=(const fse_event&); +}; diff --git a/node_modules/fsevents/src/thread.cc b/node_modules/fsevents/src/thread.cc new file mode 100644 index 00000000..4813fdc5 --- /dev/null +++ b/node_modules/fsevents/src/thread.cc @@ -0,0 +1,72 @@ +/* +** © 2014 by Philipp Dunkel <pip@pipobscure.com> +** Licensed under MIT License. +*/ + +// constants from https://developer.apple.com/library/mac/documentation/Darwin/Reference/FSEvents_Ref/index.html#//apple_ref/doc/constant_group/FSEventStreamCreateFlags +#ifndef kFSEventStreamCreateFlagNone +#define kFSEventStreamCreateFlagNone 0x00000000 +#endif + +#ifndef kFSEventStreamCreateFlagUseCFTypes +#define kFSEventStreamCreateFlagUseCFTypes 0x00000001 +#endif + +#ifndef kFSEventStreamCreateFlagNoDefer +#define kFSEventStreamCreateFlagNoDefer 0x00000002 +#endif + +#ifndef kFSEventStreamCreateFlagWatchRoot +#define kFSEventStreamCreateFlagWatchRoot 0x00000004 +#endif + +#ifndef kFSEventStreamCreateFlagIgnoreSelf +#define kFSEventStreamCreateFlagIgnoreSelf 0x00000008 +#endif + +#ifndef kFSEventStreamCreateFlagFileEvents +#define kFSEventStreamCreateFlagFileEvents 0x00000010 +#endif + +void FSEvents::threadStart() { + if (threadloop) return; + pthread_create(&thread, NULL, &FSEvents::threadRun, this); +} + +void HandleStreamEvents(ConstFSEventStreamRef stream, void *ctx, size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) { + FSEvents * fse = (FSEvents *)ctx; + size_t idx; + fse->lock(); + for (idx=0; idx < numEvents; idx++) { + fse_event *event = new fse_event( + (CFStringRef)CFArrayGetValueAtIndex((CFArrayRef)eventPaths, idx), + eventFlags[idx], + eventIds[idx] + ); + fse->events.push_back(event); + } + fse->asyncTrigger(); + fse->unlock(); +} + +void *FSEvents::threadRun(void *ctx) { + FSEvents *fse = (FSEvents*)ctx; + FSEventStreamContext context = { 0, ctx, NULL, NULL, NULL }; + fse->threadloop = CFRunLoopGetCurrent(); + FSEventStreamRef stream = FSEventStreamCreate(NULL, &HandleStreamEvents, &context, fse->paths, kFSEventStreamEventIdSinceNow, (CFAbsoluteTime) 0.1, kFSEventStreamCreateFlagNone | kFSEventStreamCreateFlagWatchRoot | kFSEventStreamCreateFlagFileEvents | kFSEventStreamCreateFlagUseCFTypes); + FSEventStreamScheduleWithRunLoop(stream, fse->threadloop, kCFRunLoopDefaultMode); + FSEventStreamStart(stream); + CFRunLoopRun(); + FSEventStreamStop(stream); + FSEventStreamUnscheduleFromRunLoop(stream, fse->threadloop, kCFRunLoopDefaultMode); + FSEventStreamInvalidate(stream); + FSEventStreamRelease(stream); + fse->threadloop = NULL; + return NULL; +} + +void FSEvents::threadStop() { + if (!threadloop) return; + CFRunLoopStop(threadloop); + pthread_join(thread, NULL); +} |
