dirmonitor: use pipes on fsevents (#1274)

As suggested by Guldoman this change introduces the usage
of pipes to allow blocking the get changes call until any
file system changes are received, which now properly reduces
the cpu usage on idle to 0%.

This change better fixes #1237
This commit is contained in:
Jefferson González 2022-12-27 23:07:12 -04:00 committed by GitHub
parent 271a804986
commit 141d00795c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 11 additions and 5 deletions

View File

@ -6,6 +6,7 @@ struct dirmonitor_internal {
char** changes; char** changes;
size_t count; size_t count;
FSEventStreamRef stream; FSEventStreamRef stream;
int fds[2];
}; };
CFRunLoopRef main_run_loop; CFRunLoopRef main_run_loop;
@ -39,6 +40,9 @@ static void stop_monitor_stream(struct dirmonitor_internal* monitor) {
monitor->stream = NULL; monitor->stream = NULL;
SDL_LockMutex(monitor->lock); SDL_LockMutex(monitor->lock);
write(monitor->fds[1], "", 1);
close(monitor->fds[0]);
close(monitor->fds[1]);
if (monitor->count > 0) { if (monitor->count > 0) {
for (size_t i = 0; i<monitor->count; i++) { for (size_t i = 0; i<monitor->count; i++) {
free(monitor->changes[i]); free(monitor->changes[i]);
@ -92,6 +96,9 @@ static void stream_callback(
strcpy(monitor->changes[idx], path_list[pidx]); strcpy(monitor->changes[idx], path_list[pidx]);
} }
monitor->count = total; monitor->count = total;
if (total > 0)
write(monitor->fds[1], "", 1);
SDL_UnlockMutex(monitor->lock); SDL_UnlockMutex(monitor->lock);
} }
@ -101,16 +108,14 @@ int get_changes_dirmonitor(
char* buffer, char* buffer,
int buffer_size int buffer_size
) { ) {
FSEventStreamFlushSync(monitor->stream); char response[1];
read(monitor->fds[0], response, 1);
size_t results = 0; size_t results = 0;
SDL_LockMutex(monitor->lock); SDL_LockMutex(monitor->lock);
results = monitor->count; results = monitor->count;
SDL_UnlockMutex(monitor->lock); SDL_UnlockMutex(monitor->lock);
if (monitor->count <= 0)
SDL_Delay(100);
return results; return results;
} }
@ -141,6 +146,7 @@ int add_dirmonitor(struct dirmonitor_internal* monitor, const char* path) {
stop_monitor_stream(monitor); stop_monitor_stream(monitor);
monitor->lock = SDL_CreateMutex(); monitor->lock = SDL_CreateMutex();
pipe(monitor->fds);
FSEventStreamContext context = { FSEventStreamContext context = {
.info = monitor, .info = monitor,
@ -160,7 +166,7 @@ int add_dirmonitor(struct dirmonitor_internal* monitor, const char* path) {
&context, &context,
CFArrayCreate(NULL, (const void **)&paths, 1, NULL), CFArrayCreate(NULL, (const void **)&paths, 1, NULL),
kFSEventStreamEventIdSinceNow, kFSEventStreamEventIdSinceNow,
10000, 0,
kFSEventStreamCreateFlagNone kFSEventStreamCreateFlagNone
| kFSEventStreamCreateFlagWatchRoot | kFSEventStreamCreateFlagWatchRoot
| kFSEventStreamCreateFlagFileEvents | kFSEventStreamCreateFlagFileEvents