1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2024-11-25 17:53:47 +00:00

fixed to dmon win32 backend (made a PR)

This commit is contained in:
fgenesis 2024-06-27 23:43:50 +02:00
parent f71c7f5d40
commit 2373fd7170

View file

@ -402,9 +402,8 @@ typedef struct dmon__state {
int freelist[DMON_MAX_WATCHES];
HANDLE thread_handle;
CRITICAL_SECTION mutex;
volatile LONG modify_watches;
dmon__win32_event* events;
bool quit;
volatile bool quit;
} dmon__state;
static bool _dmon_init;
@ -500,29 +499,30 @@ _DMON_PRIVATE DWORD WINAPI _dmon_thread(LPVOID arg)
uint64_t msecs_elapsed = 0;
while (!_dmon.quit) {
int i;
if (_dmon.modify_watches || !TryEnterCriticalSection(&_dmon.mutex)) {
if (!TryEnterCriticalSection(&_dmon.mutex)) {
Sleep(DMON_SLEEP_INTERVAL);
continue;
}
if (_dmon.num_watches == 0) {
Sleep(DMON_SLEEP_INTERVAL);
LeaveCriticalSection(&_dmon.mutex);
Sleep(DMON_SLEEP_INTERVAL);
continue;
}
for (i = 0; i < DMON_MAX_WATCHES; i++) {
if (_dmon.watches[i]) {
dmon__watch_state* watch = _dmon.watches[i];
watch_states[i] = watch;
wait_handles[i] = watch->overlapped.hEvent;
DWORD active = 0;
for (unsigned i = 0; i < DMON_MAX_WATCHES; i++) {
dmon__watch_state* watch = _dmon.watches[i];
if (watch) {
watch_states[active] = watch;
wait_handles[active] = watch->overlapped.hEvent;
++active;
}
}
DWORD wait_result = WaitForMultipleObjects(_dmon.num_watches, wait_handles, FALSE, 10);
DWORD wait_result = WaitForMultipleObjects(active, wait_handles, FALSE, 10);
DMON_ASSERT(wait_result != WAIT_FAILED);
if (wait_result != WAIT_TIMEOUT) {
if (wait_result >= WAIT_OBJECT_0 && wait_result < WAIT_OBJECT_0 + active) {
dmon__watch_state* watch = watch_states[wait_result - WAIT_OBJECT_0];
DMON_ASSERT(HasOverlappedIoCompleted(&watch->overlapped));
@ -590,7 +590,10 @@ DMON_API_IMPL void dmon_init(void)
DMON_ASSERT(_dmon.thread_handle);
for (int i = 0; i < DMON_MAX_WATCHES; i++)
{
_dmon.freelist[i] = DMON_MAX_WATCHES - i - 1;
_dmon.watches[i] = NULL;
}
_dmon_init = true;
}
@ -605,13 +608,10 @@ DMON_API_IMPL void dmon_deinit(void)
CloseHandle(_dmon.thread_handle);
}
{
int i;
for (i = 0; i < DMON_MAX_WATCHES; i++) {
if (_dmon.watches[i]) {
_dmon_unwatch(_dmon.watches[i]);
DMON_FREE(_dmon.watches[i]);
}
for (unsigned i = 0; i < DMON_MAX_WATCHES; i++) {
if (_dmon.watches[i]) {
_dmon_unwatch(_dmon.watches[i]);
DMON_FREE(_dmon.watches[i]);
}
}
@ -631,36 +631,60 @@ DMON_API_IMPL dmon_watch_id dmon_watch(const char* rootdir,
DMON_ASSERT(watch_cb);
DMON_ASSERT(rootdir && rootdir[0]);
_InterlockedExchange(&_dmon.modify_watches, 1);
EnterCriticalSection(&_dmon.mutex);
DMON_ASSERT(_dmon.num_watches < DMON_MAX_WATCHES);
if (_dmon.num_watches >= DMON_MAX_WATCHES) {
DMON_LOG_ERROR("Exceeding maximum number of watches");
LeaveCriticalSection(&_dmon.mutex);
_InterlockedExchange(&_dmon.modify_watches, 0);
return _dmon_make_id(0);
}
dmon__watch_state* watch = NULL;
unsigned id = 0;
HANDLE hEvent = INVALID_HANDLE_VALUE;
HANDLE dir_handle = INVALID_HANDLE_VALUE;
int num_freelist = DMON_MAX_WATCHES - _dmon.num_watches;
int index = _dmon.freelist[num_freelist - 1];
uint32_t id = (uint32_t)(index + 1);
if (_dmon.watches[index] == NULL) {
dmon__watch_state* state = (dmon__watch_state*)DMON_MALLOC(sizeof(dmon__watch_state));
DMON_ASSERT(state);
if (state == NULL) {
LeaveCriticalSection(&_dmon.mutex);
_InterlockedExchange(&_dmon.modify_watches, 0);
return _dmon_make_id(0);
}
memset(state, 0x0, sizeof(dmon__watch_state));
_dmon.watches[index] = state;
{
_DMON_WINAPI_STR(rootdir, DMON_MAX_PATH);
dir_handle = CreateFile(_rootdir, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL);
}
++_dmon.num_watches;
if(dir_handle == INVALID_HANDLE_VALUE)
{
_DMON_LOG_ERRORF("Could not open: %s", rootdir);
goto fail;
}
dmon__watch_state* watch = _dmon.watches[index];
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(hEvent == INVALID_HANDLE_VALUE)
{
DMON_LOG_ERROR("CreateEvent() failed");
goto fail;
}
watch = (dmon__watch_state*)DMON_MALLOC(sizeof(dmon__watch_state));
if (!watch)
{
DMON_LOG_ERROR("Out of memory");
goto fail;
}
memset(watch, 0x0, sizeof(dmon__watch_state));
id = (uint32_t)(index + 1);
watch->notify_filter = FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_LAST_WRITE |
FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_SIZE;
watch->overlapped.hEvent = hEvent;
watch->dir_handle = dir_handle;
watch->id = _dmon_make_id(id);
watch->watch_flags = flags;
watch->watch_cb = watch_cb;
@ -674,60 +698,57 @@ DMON_API_IMPL dmon_watch_id dmon_watch(const char* rootdir,
watch->rootdir[rootdir_len + 1] = '\0';
}
_DMON_WINAPI_STR(rootdir, DMON_MAX_PATH);
watch->dir_handle =
CreateFile(_rootdir, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
if (watch->dir_handle != INVALID_HANDLE_VALUE) {
watch->notify_filter = FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_LAST_WRITE |
FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_SIZE;
watch->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
DMON_ASSERT(watch->overlapped.hEvent != INVALID_HANDLE_VALUE);
if (!_dmon_refresh_watch(watch)) {
_dmon_unwatch(watch);
DMON_LOG_ERROR("ReadDirectoryChanges failed");
LeaveCriticalSection(&_dmon.mutex);
_InterlockedExchange(&_dmon.modify_watches, 0);
return _dmon_make_id(0);
}
} else {
_DMON_LOG_ERRORF("Could not open: %s", rootdir);
LeaveCriticalSection(&_dmon.mutex);
_InterlockedExchange(&_dmon.modify_watches, 0);
return _dmon_make_id(0);
if (!_dmon_refresh_watch(watch)) {
_dmon_unwatch(watch);
DMON_LOG_ERROR("ReadDirectoryChanges failed");
goto fail;
}
++_dmon.num_watches;
finish:
_dmon.watches[index] = watch;
LeaveCriticalSection(&_dmon.mutex);
_InterlockedExchange(&_dmon.modify_watches, 0);
return _dmon_make_id(id);
fail:
if(hEvent != INVALID_HANDLE_VALUE)
CloseHandle(hEvent);
if(dir_handle != INVALID_HANDLE_VALUE)
CloseHandle(dir_handle);
if(watch)
{
DMON_FREE(watch);
watch = NULL;
};
id = 0;
goto finish;
}
DMON_API_IMPL void dmon_unwatch(dmon_watch_id id)
{
EnterCriticalSection(&_dmon.mutex);
DMON_ASSERT(_dmon_init);
DMON_ASSERT(id.id > 0);
int index = id.id - 1;
DMON_ASSERT(index < DMON_MAX_WATCHES);
DMON_ASSERT(_dmon.watches[index]);
DMON_ASSERT(_dmon.num_watches > 0);
if (_dmon.watches[index]) {
_InterlockedExchange(&_dmon.modify_watches, 1);
EnterCriticalSection(&_dmon.mutex);
dmon__watch_state* watch = _dmon.watches[index];
DMON_ASSERT(watch);
_dmon_unwatch(_dmon.watches[index]);
DMON_FREE(_dmon.watches[index]);
if (watch) {
_dmon_unwatch(watch);
DMON_FREE(watch);
_dmon.watches[index] = NULL;
--_dmon.num_watches;
int num_freelist = DMON_MAX_WATCHES - _dmon.num_watches;
_dmon.freelist[num_freelist - 1] = index;
LeaveCriticalSection(&_dmon.mutex);
_InterlockedExchange(&_dmon.modify_watches, 0);
}
LeaveCriticalSection(&_dmon.mutex);
}
#elif DMON_OS_LINUX