6#if defined(DART_HOST_OS_MACOS)
12#include <CoreServices/CoreServices.h>
25#ifndef MAC_OS_X_VERSION_10_7
26enum { kFSEventStreamCreateFlagFileEvents = 0x00000010 };
28 kFSEventStreamEventFlagItemCreated = 0x00000100,
29 kFSEventStreamEventFlagItemRemoved = 0x00000200,
30 kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400,
31 kFSEventStreamEventFlagItemRenamed = 0x00000800,
32 kFSEventStreamEventFlagItemModified = 0x00001000,
33 kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000,
34 kFSEventStreamEventFlagItemChangeOwner = 0x00004000,
35 kFSEventStreamEventFlagItemXattrMod = 0x00008000,
36 kFSEventStreamEventFlagItemIsFile = 0x00010000,
37 kFSEventStreamEventFlagItemIsDir = 0x00020000,
38 kFSEventStreamEventFlagItemIsSymlink = 0x00040000
54class FSEventsWatcher {
58 Node(FSEventsWatcher* watcher,
64 base_path_length_(strlen(base_path)),
65 path_ref_(CFStringCreateWithCString(nullptr,
67 kCFStringEncodingUTF8)),
70 recursive_(recursive),
86 void set_ref(FSEventStreamRef ref) { ref_ = ref; }
89 FSEventStreamContext context;
90 memset(&context, 0,
sizeof(context));
91 context.info =
reinterpret_cast<void*
>(
this);
92 context.release = [](
const void*
info) {
93 delete static_cast<const Node*
>(
info);
95 CFArrayRef array = CFArrayCreate(
96 nullptr,
reinterpret_cast<const void**
>(&path_ref_), 1,
nullptr);
97 FSEventStreamRef ref = FSEventStreamCreate(
98 nullptr,
Callback, &context, array, kFSEventStreamEventIdSinceNow,
99 0.10, kFSEventStreamCreateFlagFileEvents);
104 FSEventStreamScheduleWithRunLoop(ref_, watcher_->run_loop_,
105 kCFRunLoopDefaultMode);
107 FSEventStreamStart(ref_);
108 FSEventStreamFlushSync(ref_);
112 FSEventStreamStop(ref_);
113 FSEventStreamInvalidate(ref_);
114 FSEventStreamRelease(ref_);
117 FSEventsWatcher* watcher()
const {
return watcher_; }
118 intptr_t base_path_length()
const {
return base_path_length_; }
119 int read_fd()
const {
return read_fd_; }
120 int write_fd()
const {
return write_fd_; }
121 bool recursive()
const {
return recursive_; }
124 FSEventsWatcher* watcher_;
125 intptr_t base_path_length_;
126 CFStringRef path_ref_;
130 FSEventStreamRef ref_;
135 FSEventsWatcher() : run_loop_(0) { Start(); }
140 while (run_loop_ ==
nullptr) {
147 FSEventsWatcher* watcher =
reinterpret_cast<FSEventsWatcher*
>(arg);
150 watcher->run_loop_ = CFRunLoopGetCurrent();
151 CFRetain(watcher->run_loop_);
154 watcher->monitor().Enter();
155 watcher->monitor().Notify();
156 watcher->monitor().Exit();
158 CFRunLoopTimerRef timer =
159 CFRunLoopTimerCreate(
nullptr, CFAbsoluteTimeGetCurrent() + 1, 1, 0, 0,
160 TimerCallback,
nullptr);
161 CFRunLoopAddTimer(watcher->run_loop_, timer, kCFRunLoopCommonModes);
166 CFRelease(watcher->run_loop_);
167 watcher->monitor_.Enter();
168 watcher->run_loop_ =
nullptr;
169 watcher->monitor_.Notify();
170 watcher->monitor_.Exit();
175 CFRunLoopTimerContext context;
176 memset(&context, 0,
sizeof(context));
178 CFRunLoopTimerRef timer =
179 CFRunLoopTimerCreate(
nullptr, 0, 0, 0, 0, StopCallback, &context);
180 CFRunLoopAddTimer(run_loop_, timer, kCFRunLoopCommonModes);
183 while (run_loop_ !=
nullptr) {
189 static void StopCallback(CFRunLoopTimerRef timer,
void*
info) {
190 FSEventsWatcher* watcher =
reinterpret_cast<FSEventsWatcher*
>(
info);
192 CFRunLoopStop(watcher->run_loop_);
195 ~FSEventsWatcher() { Stop(); }
197 Monitor& monitor() {
return monitor_; }
199 bool has_run_loop()
const {
return run_loop_ !=
nullptr; }
201 static void TimerCallback(CFRunLoopTimerRef timer,
void* context) {
205 Node* AddPath(
const char*
path,
int events,
bool recursive) {
212 realpath(
path, base_path);
214 return new Node(
this, base_path, fds[0], fds[1], recursive);
218 static void Callback(ConstFSEventStreamRef ref,
222 const FSEventStreamEventFlags event_flags[],
223 const FSEventStreamEventId event_ids[]) {
229 Node* node =
static_cast<Node*
>(client);
233 for (
size_t i = 0;
i < num_events;
i++) {
234 char*
path =
reinterpret_cast<char**
>(event_paths)[
i];
238 path += node->base_path_length();
240 if (
path[0] !=
'\0') {
243 if (!node->recursive() && (strstr(
path,
"/") !=
nullptr)) {
246 event.data.flags = event_flags[
i];
253 CFRunLoopRef run_loop_;
259#define kCFCoreFoundationVersionNumber10_7 635.00
261 return kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber10_7;
265 return reinterpret_cast<intptr_t
>(
new FSEventsWatcher());
269 delete reinterpret_cast<FSEventsWatcher*
>(
id);
277 FSEventsWatcher* watcher =
reinterpret_cast<FSEventsWatcher*
>(
id);
278 return reinterpret_cast<intptr_t
>(watcher->AddPath(
path, events, recursive));
283 reinterpret_cast<FSEventsWatcher::Node*
>(path_id)->Stop();
287 return reinterpret_cast<FSEventsWatcher::Node*
>(path_id)->read_fd();
293 int count = avail /
sizeof(FSEvent);
304 size_t path_len = strlen(
e.data.path);
308 if ((
flags & kFSEventStreamEventFlagItemRenamed) != 0) {
316 if ((
flags & kFSEventStreamEventFlagItemModified) != 0) {
319 if ((
flags & kFSEventStreamEventFlagItemXattrMod) != 0) {
322 if ((
flags & kFSEventStreamEventFlagItemCreated) != 0) {
325 if ((
flags & kFSEventStreamEventFlagItemIsDir) != 0) {
328 if ((
flags & kFSEventStreamEventFlagItemRemoved) != 0) {
339 reinterpret_cast<uint8_t*
>(
e.data.path), path_len);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static bool read(SkStream *stream, void *buffer, size_t amount)
#define RELEASE_ASSERT(cond)
static Dart_Handle NewDartOSError()
static intptr_t AvailableBytes(intptr_t fd)
static bool SetBlocking(intptr_t fd)
static bool SetNonBlocking(intptr_t fd)
static intptr_t GetSocketId(intptr_t id, intptr_t path_id)
static void Close(intptr_t id)
static void UnwatchPath(intptr_t id, intptr_t path_id)
static bool IsSupported()
static bool delayed_filewatch_callback()
static Dart_Handle ReadEvents(intptr_t id, intptr_t path_id)
static intptr_t WatchPath(intptr_t id, Namespace *namespc, const char *path, int events, bool recursive)
static Type GetType(Namespace *namespc, const char *path, bool follow_links)
static constexpr int64_t kNoTimeout
static int Start(const char *name, ThreadStartFunction function, uword parameters)
static bool Compare(ThreadId a, ThreadId b)
static ThreadId GetCurrentThreadId()
static void Sleep(int64_t millis)
struct _Dart_Handle * Dart_Handle
FlutterSemanticsFlag flags
DART_EXPORT Dart_Handle Dart_NewInteger(int64_t value)
DART_EXPORT Dart_Handle Dart_NewStringFromUTF8(const uint8_t *utf8_array, intptr_t length)
DART_EXPORT Dart_Handle Dart_ListSetAt(Dart_Handle list, intptr_t index, Dart_Handle value)
DART_EXPORT Dart_Handle Dart_NewBoolean(bool value)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_NewList(intptr_t length)
static int8_t data[kExtLength]
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
std::function< void(MTLRenderPipelineDescriptor *)> Callback
#define VOID_NO_RETRY_EXPECTED(expression)
#define TEMP_FAILURE_RETRY(expression)
void write(SkWStream *wStream, const T &text)