11#ifndef __clang__
2+ #include <dispatch/dispatch.h>
23#include "fsm-darwin-gcc.h"
34#else
45#include <CoreFoundation/CoreFoundation.h>
@@ -38,7 +39,9 @@ struct fsm_listen_data
3839
3940 FSEventStreamRef stream ;
4041
41- CFRunLoopRef rl ;
42+ dispatch_queue_t dq ;
43+ pthread_cond_t dq_finished ;
44+ pthread_mutex_t dq_lock ;
4245
4346 enum shutdown_style {
4447 SHUTDOWN_EVENT = 0 ,
@@ -379,8 +382,11 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef,
379382 fsmonitor_batch__free_list (batch );
380383 string_list_clear (& cookie_list , 0 );
381384
385+ pthread_mutex_lock (& data -> dq_lock );
382386 data -> shutdown_style = FORCE_SHUTDOWN ;
383- CFRunLoopStop (data -> rl );
387+ pthread_cond_broadcast (& data -> dq_finished );
388+ pthread_mutex_unlock (& data -> dq_lock );
389+
384390 strbuf_release (& tmp );
385391 return ;
386392}
@@ -441,10 +447,6 @@ int fsm_listen__ctor(struct fsmonitor_daemon_state *state)
441447 if (!data -> stream )
442448 goto failed ;
443449
444- /*
445- * `data->rl` needs to be set inside the listener thread.
446- */
447-
448450 return 0 ;
449451
450452failed :
@@ -471,6 +473,11 @@ void fsm_listen__dtor(struct fsmonitor_daemon_state *state)
471473 FSEventStreamRelease (data -> stream );
472474 }
473475
476+ if (data -> dq )
477+ dispatch_release (data -> dq );
478+ pthread_cond_destroy (& data -> dq_finished );
479+ pthread_mutex_destroy (& data -> dq_lock );
480+
474481 FREE_AND_NULL (state -> listen_data );
475482}
476483
@@ -479,9 +486,11 @@ void fsm_listen__stop_async(struct fsmonitor_daemon_state *state)
479486 struct fsm_listen_data * data ;
480487
481488 data = state -> listen_data ;
482- data -> shutdown_style = SHUTDOWN_EVENT ;
483489
484- CFRunLoopStop (data -> rl );
490+ pthread_mutex_lock (& data -> dq_lock );
491+ data -> shutdown_style = SHUTDOWN_EVENT ;
492+ pthread_cond_broadcast (& data -> dq_finished );
493+ pthread_mutex_unlock (& data -> dq_lock );
485494}
486495
487496void fsm_listen__loop (struct fsmonitor_daemon_state * state )
@@ -490,9 +499,11 @@ void fsm_listen__loop(struct fsmonitor_daemon_state *state)
490499
491500 data = state -> listen_data ;
492501
493- data -> rl = CFRunLoopGetCurrent ();
502+ pthread_mutex_init (& data -> dq_lock , NULL );
503+ pthread_cond_init (& data -> dq_finished , NULL );
504+ data -> dq = dispatch_queue_create ("FSMonitor" , NULL );
494505
495- FSEventStreamScheduleWithRunLoop (data -> stream , data -> rl , kCFRunLoopDefaultMode );
506+ FSEventStreamSetDispatchQueue (data -> stream , data -> dq );
496507 data -> stream_scheduled = 1 ;
497508
498509 if (!FSEventStreamStart (data -> stream )) {
@@ -501,7 +512,9 @@ void fsm_listen__loop(struct fsmonitor_daemon_state *state)
501512 }
502513 data -> stream_started = 1 ;
503514
504- CFRunLoopRun ();
515+ pthread_mutex_lock (& data -> dq_lock );
516+ pthread_cond_wait (& data -> dq_finished , & data -> dq_lock );
517+ pthread_mutex_unlock (& data -> dq_lock );
505518
506519 switch (data -> shutdown_style ) {
507520 case FORCE_ERROR_STOP :
0 commit comments