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:
parent
271a804986
commit
141d00795c
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue