277 using T_AsyncLoopWakeUp =
typename T_AsyncEventLoop::LoopWakeUp;
278 using T_AsyncFileReadiness =
typename T_AsyncEventLoop::FileReadiness;
279 using T_AsyncExternalCompletion =
typename T_AsyncEventLoop::ExternalCompletion;
280 using T_EventObject =
typename T_AsyncEventLoop::EventObjectType;
281 using T_AsyncResult =
typename T_AsyncEventLoop::ResultType;
283 void init(T_AsyncEventLoop& loop) { eventLoop = &loop; }
286 T_AsyncEventLoop* eventLoop =
nullptr;
289 virtual Result appleStartWakeUp()
override
291 if (eventLoop ==
nullptr or fileSystemWatcher ==
nullptr)
292 return Result::Error(FileSystemWatcherResultCategory, FileSystemWatcherError::NotInitialized);
293 T_AsyncLoopWakeUp& wakeUp = asyncWakeUp;
294 wakeUp.callback.template bind<Self, &Self::onEventLoopNotification>(*
this);
295 return wakeUp.start(*eventLoop);
298 virtual void appleSignalEventObject()
override { eventObject.signal(); }
300 virtual Result appleStopWakeUp()
override
302 notificationGeneration++;
303 if (not asyncWakeUp.isFree())
305 SC_TRY(asyncWakeUp.stop(*eventLoop));
306 while (not asyncWakeUp.isFree())
308 SC_TRY(eventLoop->runNoWait());
312 eventObject.signal();
317 virtual Result appleWakeUpAndWait()
override
319 const Result res = asyncWakeUp.wakeUp(*eventLoop);
324 void onEventLoopNotification(
typename T_AsyncLoopWakeUp::Result& result)
326 const size_t generation = notificationGeneration;
327 result.reactivateRequest(
true);
328 fileSystemWatcher->asyncNotify(
nullptr);
329 if (generation == notificationGeneration)
331 eventObject.signal();
335 size_t notificationGeneration = 0;
337 T_AsyncLoopWakeUp asyncWakeUp = {};
338 T_EventObject eventObject = {};
339#elif SC_PLATFORM_LINUX
340 virtual Result linuxStartSharedFileReadiness()
override
342 if (eventLoop ==
nullptr or fileSystemWatcher ==
nullptr)
343 return Result::Error(FileSystemWatcherResultCategory, FileSystemWatcherError::NotInitialized);
344 SC_TRY(eventLoop->associateExternallyCreatedFileDescriptorHandle(notifyFd));
345 asyncPoll.callback.template bind<Self, &Self::onEventLoopNotification>(*
this);
346 return asyncPoll.start(*eventLoop, notifyFd);
349 virtual Result linuxStopSharedFileReadiness()
override {
return asyncPoll.stop(*eventLoop); }
351 void onEventLoopNotification(
typename T_AsyncFileReadiness::Result& result)
353 fileSystemWatcher->asyncNotify(
nullptr);
354 result.reactivateRequest(
true);
357 T_AsyncFileReadiness asyncPoll = {};
360 virtual Result windowsStartFolderExternalCompletion(
FolderWatcher& watcher,
void* handle)
override
362 if (eventLoop ==
nullptr or fileSystemWatcher ==
nullptr)
363 return Result::Error(FileSystemWatcherResultCategory, FileSystemWatcherError::NotInitialized);
364 T_AsyncExternalCompletion& completion =
365 watcher.asyncStorage.template reinterpret_as<T_AsyncExternalCompletion>();
366 placementNew(completion);
367 completion.setDebugName(
"FileSystemWatcherAsync Completion");
368 completion.callback.template bind<Self, &Self::onEventLoopNotification>(*
this);
369 return completion.start(*eventLoop, handle);
372 virtual Result windowsRequestStopFolderExternalCompletion(
FolderWatcher& watcher)
override
374 T_AsyncExternalCompletion& completion =
375 watcher.asyncStorage.template reinterpret_as<T_AsyncExternalCompletion>();
377 windowsFolderCompletionStopped =
false;
378 onAsyncCompletionClose = [
this, &watcher](T_AsyncResult&)
380 T_AsyncExternalCompletion& completion =
381 watcher.asyncStorage.template reinterpret_as<T_AsyncExternalCompletion>();
382 completion.~T_AsyncExternalCompletion();
383 windowsFolderCompletionStopped =
true;
385 return completion.stop(*eventLoop, &onAsyncCompletionClose);
388 virtual Result windowsWaitFolderExternalCompletionStopped(
FolderWatcher&)
override
390 while (not windowsFolderCompletionStopped)
392 SC_TRY(eventLoop->runOnce());
397 virtual Result windowsMarkFolderExternalCompletionPending(
FolderWatcher& watcher)
override
399 T_AsyncExternalCompletion& completion =
400 watcher.asyncStorage.template reinterpret_as<T_AsyncExternalCompletion>();
401 return completion.markSubmissionPending();
404 virtual Result windowsClearFolderExternalCompletionPending(
FolderWatcher& watcher)
override
406 T_AsyncExternalCompletion& completion =
407 watcher.asyncStorage.template reinterpret_as<T_AsyncExternalCompletion>();
408 return completion.clearSubmissionPending();
411 virtual void* windowsGetOverlapped(
FolderWatcher& watcher)
override
413 T_AsyncExternalCompletion& completion =
414 watcher.asyncStorage.template reinterpret_as<T_AsyncExternalCompletion>();
415 return completion.getWindowsOverlapped();
418 void onEventLoopNotification(
typename T_AsyncExternalCompletion::Result& result)
420 SC_COMPILER_WARNING_PUSH_OFFSETOF;
421 auto& storage =
reinterpret_cast<decltype(FolderWatcher::asyncStorage)&
>(result.getAsync());
423 fileSystemWatcher->asyncNotify(&watcher, result.completionData.bytesTransferred);
424 if (watcher.parent !=
nullptr and result.getAsync().hasSubmissionPending())
426 result.reactivateRequest(
true);
428 SC_COMPILER_WARNING_POP_OFFSETOF;
431 Function<void(T_AsyncResult&)> onAsyncCompletionClose;
432 bool windowsFolderCompletionStopped =
false;