Move to dmon.h new version to test
By doing so we removed the addition of dmon_watch_rm and the Lua code will no longer compile.
This commit is contained in:
parent
c08b76746b
commit
ff86d54ff5
96
src/dmon.h
96
src/dmon.h
|
@ -5,7 +5,6 @@
|
||||||
// Portable directory monitoring library
|
// Portable directory monitoring library
|
||||||
// watches directories for file or directory changes.
|
// watches directories for file or directory changes.
|
||||||
//
|
//
|
||||||
// clang-format off
|
|
||||||
// Usage:
|
// Usage:
|
||||||
// define DMON_IMPL and include this file to use it:
|
// define DMON_IMPL and include this file to use it:
|
||||||
// #define DMON_IMPL
|
// #define DMON_IMPL
|
||||||
|
@ -116,7 +115,6 @@ DMON_API_DECL dmon_watch_id dmon_watch(const char* rootdir,
|
||||||
uint32_t flags, void* user_data);
|
uint32_t flags, void* user_data);
|
||||||
DMON_API_DECL void dmon_unwatch(dmon_watch_id id);
|
DMON_API_DECL void dmon_unwatch(dmon_watch_id id);
|
||||||
DMON_API_DECL bool dmon_watch_add(dmon_watch_id id, const char* subdir);
|
DMON_API_DECL bool dmon_watch_add(dmon_watch_id id, const char* subdir);
|
||||||
DMON_API_DECL bool dmon_watch_rm(dmon_watch_id id, const char* subdir);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -396,8 +394,6 @@ typedef struct dmon__state {
|
||||||
static bool _dmon_init;
|
static bool _dmon_init;
|
||||||
static dmon__state _dmon;
|
static dmon__state _dmon;
|
||||||
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
_DMON_PRIVATE bool dmon__refresh_watch(dmon__watch_state* watch)
|
_DMON_PRIVATE bool dmon__refresh_watch(dmon__watch_state* watch)
|
||||||
{
|
{
|
||||||
return ReadDirectoryChangesW(watch->dir_handle, watch->buffer, sizeof(watch->buffer),
|
return ReadDirectoryChangesW(watch->dir_handle, watch->buffer, sizeof(watch->buffer),
|
||||||
|
@ -703,7 +699,6 @@ typedef struct dmon__state {
|
||||||
dmon__watch_state watches[DMON_MAX_WATCHES];
|
dmon__watch_state watches[DMON_MAX_WATCHES];
|
||||||
dmon__inotify_event* events;
|
dmon__inotify_event* events;
|
||||||
int num_watches;
|
int num_watches;
|
||||||
volatile int modify_watches;
|
|
||||||
pthread_t thread_handle;
|
pthread_t thread_handle;
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
bool quit;
|
bool quit;
|
||||||
|
@ -771,7 +766,11 @@ DMON_API_IMPL bool dmon_watch_add(dmon_watch_id id, const char* watchdir)
|
||||||
{
|
{
|
||||||
DMON_ASSERT(id.id > 0 && id.id <= DMON_MAX_WATCHES);
|
DMON_ASSERT(id.id > 0 && id.id <= DMON_MAX_WATCHES);
|
||||||
|
|
||||||
|
bool skip_lock = pthread_self() == _dmon.thread_handle;
|
||||||
|
|
||||||
|
if (!skip_lock)
|
||||||
pthread_mutex_lock(&_dmon.mutex);
|
pthread_mutex_lock(&_dmon.mutex);
|
||||||
|
|
||||||
dmon__watch_state* watch = &_dmon.watches[id.id - 1];
|
dmon__watch_state* watch = &_dmon.watches[id.id - 1];
|
||||||
|
|
||||||
// check if the directory exists
|
// check if the directory exists
|
||||||
|
@ -790,6 +789,7 @@ DMON_API_IMPL bool dmon_watch_add(dmon_watch_id id, const char* watchdir)
|
||||||
dmon__strcat(fullpath, sizeof(fullpath), watchdir);
|
dmon__strcat(fullpath, sizeof(fullpath), watchdir);
|
||||||
if (stat(fullpath, &st) != 0 || (st.st_mode & S_IFDIR) == 0) {
|
if (stat(fullpath, &st) != 0 || (st.st_mode & S_IFDIR) == 0) {
|
||||||
_DMON_LOG_ERRORF("Watch directory '%s' is not valid", watchdir);
|
_DMON_LOG_ERRORF("Watch directory '%s' is not valid", watchdir);
|
||||||
|
if (!skip_lock)
|
||||||
pthread_mutex_unlock(&_dmon.mutex);
|
pthread_mutex_unlock(&_dmon.mutex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -802,14 +802,24 @@ DMON_API_IMPL bool dmon_watch_add(dmon_watch_id id, const char* watchdir)
|
||||||
subdir.rootdir[dirlen + 1] = '\0';
|
subdir.rootdir[dirlen + 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check that the directory is not already added
|
||||||
|
for (int i = 0, c = stb_sb_count(watch->subdirs); i < c; i++) {
|
||||||
|
if (strcmp(subdir.rootdir, watch->subdirs[i].rootdir) == 0) {
|
||||||
|
_DMON_LOG_ERRORF("Error watching directory '%s', because it is already added.", watchdir);
|
||||||
|
if (!skip_lock)
|
||||||
|
pthread_mutex_unlock(&_dmon.mutex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const uint32_t inotify_mask = IN_MOVED_TO | IN_CREATE | IN_MOVED_FROM | IN_DELETE | IN_MODIFY;
|
const uint32_t inotify_mask = IN_MOVED_TO | IN_CREATE | IN_MOVED_FROM | IN_DELETE | IN_MODIFY;
|
||||||
char fullpath[DMON_MAX_PATH];
|
char fullpath[DMON_MAX_PATH];
|
||||||
|
|
||||||
dmon__strcpy(fullpath, sizeof(fullpath), watch->rootdir);
|
dmon__strcpy(fullpath, sizeof(fullpath), watch->rootdir);
|
||||||
dmon__strcat(fullpath, sizeof(fullpath), subdir.rootdir);
|
dmon__strcat(fullpath, sizeof(fullpath), subdir.rootdir);
|
||||||
int wd = inotify_add_watch(watch->fd, fullpath, inotify_mask);
|
int wd = inotify_add_watch(watch->fd, fullpath, inotify_mask);
|
||||||
if (wd == -1) {
|
if (wd == -1) {
|
||||||
_DMON_LOG_ERRORF("Error watching directory '%s'. (inotify_add_watch:err=%d)", watchdir, errno);
|
_DMON_LOG_ERRORF("Error watching directory '%s'. (inotify_add_watch:err=%d)", watchdir, errno);
|
||||||
|
if (!skip_lock)
|
||||||
pthread_mutex_unlock(&_dmon.mutex);
|
pthread_mutex_unlock(&_dmon.mutex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -817,56 +827,9 @@ DMON_API_IMPL bool dmon_watch_add(dmon_watch_id id, const char* watchdir)
|
||||||
stb_sb_push(watch->subdirs, subdir);
|
stb_sb_push(watch->subdirs, subdir);
|
||||||
stb_sb_push(watch->wds, wd);
|
stb_sb_push(watch->wds, wd);
|
||||||
|
|
||||||
|
if (!skip_lock)
|
||||||
pthread_mutex_unlock(&_dmon.mutex);
|
pthread_mutex_unlock(&_dmon.mutex);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
DMON_API_IMPL bool dmon_watch_rm(dmon_watch_id id, const char* watchdir)
|
|
||||||
{
|
|
||||||
DMON_ASSERT(id.id > 0 && id.id <= DMON_MAX_WATCHES);
|
|
||||||
|
|
||||||
pthread_mutex_lock(&_dmon.mutex);
|
|
||||||
dmon__watch_state* watch = &_dmon.watches[id.id - 1];
|
|
||||||
|
|
||||||
char subdir[DMON_MAX_PATH];
|
|
||||||
dmon__strcpy(subdir, sizeof(subdir), watchdir);
|
|
||||||
if (strstr(subdir, watch->rootdir) == subdir) {
|
|
||||||
dmon__strcpy(subdir, sizeof(subdir), watchdir + strlen(watch->rootdir));
|
|
||||||
}
|
|
||||||
|
|
||||||
int dirlen = (int)strlen(subdir);
|
|
||||||
if (subdir[dirlen - 1] != '/') {
|
|
||||||
subdir[dirlen] = '/';
|
|
||||||
subdir[dirlen + 1] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
int i, c = stb_sb_count(watch->subdirs);
|
|
||||||
for (i = 0; i < c; i++) {
|
|
||||||
fprintf(stderr, "compare >%s< >%s<\n", watch->subdirs[i].rootdir, subdir);
|
|
||||||
if (strcmp(watch->subdirs[i].rootdir, subdir) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i >= c) {
|
|
||||||
_DMON_LOG_ERRORF("Watch directory '%s' is not valid", watchdir);
|
|
||||||
pthread_mutex_unlock(&_dmon.mutex);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
inotify_rm_watch(watch->fd, watch->wds[i]);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* FIXME: in theory we should remove the entry but if done we can get a
|
|
||||||
** fail in the dmon__thread when looking up for the subdir with
|
|
||||||
** dmon__find_subdir */
|
|
||||||
for (int j = i; j < c - 1; j++) {
|
|
||||||
memcpy(watch->subdirs + j, watch->subdirs + j + 1, sizeof(dmon__watch_subdir));
|
|
||||||
memcpy(watch->wds + j, watch->wds + j + 1, sizeof(int));
|
|
||||||
}
|
|
||||||
stb__sbraw(watch->subdirs)[1] = c - 1;
|
|
||||||
stb__sbraw(watch->wds)[1] = c - 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&_dmon.mutex);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1088,15 +1051,8 @@ static void* dmon__thread(void* arg)
|
||||||
gettimeofday(&starttm, 0);
|
gettimeofday(&starttm, 0);
|
||||||
|
|
||||||
while (!_dmon.quit) {
|
while (!_dmon.quit) {
|
||||||
|
|
||||||
if (_dmon.modify_watches || pthread_mutex_trylock(&_dmon.mutex) != 0) {
|
|
||||||
nanosleep(&req, &rem);
|
nanosleep(&req, &rem);
|
||||||
continue;
|
if (_dmon.num_watches == 0 || pthread_mutex_trylock(&_dmon.mutex) != 0) {
|
||||||
}
|
|
||||||
|
|
||||||
if (_dmon.num_watches == 0) {
|
|
||||||
nanosleep(&req, &rem);
|
|
||||||
pthread_mutex_unlock(&_dmon.mutex);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1110,11 +1066,7 @@ static void* dmon__thread(void* arg)
|
||||||
|
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
timeout.tv_usec = 100000;
|
timeout.tv_usec = 100000;
|
||||||
/* FIXME: the unlock/lock around select are a temporary solution to avoid
|
|
||||||
** a deadlock with dmon_watch_add. */
|
|
||||||
pthread_mutex_unlock(&_dmon.mutex);
|
|
||||||
if (select(FD_SETSIZE, &rfds, NULL, NULL, &timeout)) {
|
if (select(FD_SETSIZE, &rfds, NULL, NULL, &timeout)) {
|
||||||
pthread_mutex_lock(&_dmon.mutex);
|
|
||||||
for (int i = 0; i < _dmon.num_watches; i++) {
|
for (int i = 0; i < _dmon.num_watches; i++) {
|
||||||
dmon__watch_state* watch = &_dmon.watches[i];
|
dmon__watch_state* watch = &_dmon.watches[i];
|
||||||
if (FD_ISSET(watch->fd, &rfds)) {
|
if (FD_ISSET(watch->fd, &rfds)) {
|
||||||
|
@ -1204,7 +1156,6 @@ DMON_API_IMPL dmon_watch_id dmon_watch(const char* rootdir,
|
||||||
DMON_ASSERT(watch_cb);
|
DMON_ASSERT(watch_cb);
|
||||||
DMON_ASSERT(rootdir && rootdir[0]);
|
DMON_ASSERT(rootdir && rootdir[0]);
|
||||||
|
|
||||||
__sync_lock_test_and_set(&_dmon.modify_watches, 1);
|
|
||||||
pthread_mutex_lock(&_dmon.mutex);
|
pthread_mutex_lock(&_dmon.mutex);
|
||||||
|
|
||||||
DMON_ASSERT(_dmon.num_watches < DMON_MAX_WATCHES);
|
DMON_ASSERT(_dmon.num_watches < DMON_MAX_WATCHES);
|
||||||
|
@ -1221,7 +1172,6 @@ DMON_API_IMPL dmon_watch_id dmon_watch(const char* rootdir,
|
||||||
(root_st.st_mode & S_IRUSR) != S_IRUSR) {
|
(root_st.st_mode & S_IRUSR) != S_IRUSR) {
|
||||||
_DMON_LOG_ERRORF("Could not open/read directory: %s", rootdir);
|
_DMON_LOG_ERRORF("Could not open/read directory: %s", rootdir);
|
||||||
pthread_mutex_unlock(&_dmon.mutex);
|
pthread_mutex_unlock(&_dmon.mutex);
|
||||||
__sync_lock_test_and_set(&_dmon.modify_watches, 0);
|
|
||||||
return dmon__make_id(0);
|
return dmon__make_id(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1238,7 +1188,6 @@ DMON_API_IMPL dmon_watch_id dmon_watch(const char* rootdir,
|
||||||
_DMON_LOG_ERRORF("symlinks are unsupported: %s. use DMON_WATCHFLAGS_FOLLOW_SYMLINKS",
|
_DMON_LOG_ERRORF("symlinks are unsupported: %s. use DMON_WATCHFLAGS_FOLLOW_SYMLINKS",
|
||||||
rootdir);
|
rootdir);
|
||||||
pthread_mutex_unlock(&_dmon.mutex);
|
pthread_mutex_unlock(&_dmon.mutex);
|
||||||
__sync_lock_test_and_set(&_dmon.modify_watches, 0);
|
|
||||||
return dmon__make_id(0);
|
return dmon__make_id(0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1256,7 +1205,6 @@ DMON_API_IMPL dmon_watch_id dmon_watch(const char* rootdir,
|
||||||
if (watch->fd < -1) {
|
if (watch->fd < -1) {
|
||||||
DMON_LOG_ERROR("could not create inotify instance");
|
DMON_LOG_ERROR("could not create inotify instance");
|
||||||
pthread_mutex_unlock(&_dmon.mutex);
|
pthread_mutex_unlock(&_dmon.mutex);
|
||||||
__sync_lock_test_and_set(&_dmon.modify_watches, 0);
|
|
||||||
return dmon__make_id(0);
|
return dmon__make_id(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1265,7 +1213,6 @@ DMON_API_IMPL dmon_watch_id dmon_watch(const char* rootdir,
|
||||||
if (wd < 0) {
|
if (wd < 0) {
|
||||||
_DMON_LOG_ERRORF("Error watching directory '%s'. (inotify_add_watch:err=%d)", watch->rootdir, errno);
|
_DMON_LOG_ERRORF("Error watching directory '%s'. (inotify_add_watch:err=%d)", watch->rootdir, errno);
|
||||||
pthread_mutex_unlock(&_dmon.mutex);
|
pthread_mutex_unlock(&_dmon.mutex);
|
||||||
__sync_lock_test_and_set(&_dmon.modify_watches, 0);
|
|
||||||
return dmon__make_id(0);
|
return dmon__make_id(0);
|
||||||
}
|
}
|
||||||
dmon__watch_subdir subdir;
|
dmon__watch_subdir subdir;
|
||||||
|
@ -1281,7 +1228,6 @@ DMON_API_IMPL dmon_watch_id dmon_watch(const char* rootdir,
|
||||||
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&_dmon.mutex);
|
pthread_mutex_unlock(&_dmon.mutex);
|
||||||
__sync_lock_test_and_set(&_dmon.modify_watches, 0);
|
|
||||||
return dmon__make_id(id);
|
return dmon__make_id(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1289,7 +1235,6 @@ DMON_API_IMPL void dmon_unwatch(dmon_watch_id id)
|
||||||
{
|
{
|
||||||
DMON_ASSERT(id.id > 0);
|
DMON_ASSERT(id.id > 0);
|
||||||
|
|
||||||
__sync_lock_test_and_set(&_dmon.modify_watches, 1);
|
|
||||||
pthread_mutex_lock(&_dmon.mutex);
|
pthread_mutex_lock(&_dmon.mutex);
|
||||||
|
|
||||||
int index = id.id - 1;
|
int index = id.id - 1;
|
||||||
|
@ -1302,9 +1247,7 @@ DMON_API_IMPL void dmon_unwatch(dmon_watch_id id)
|
||||||
--_dmon.num_watches;
|
--_dmon.num_watches;
|
||||||
|
|
||||||
pthread_mutex_unlock(&_dmon.mutex);
|
pthread_mutex_unlock(&_dmon.mutex);
|
||||||
__sync_lock_test_and_set(&_dmon.modify_watches, 0);
|
|
||||||
}
|
}
|
||||||
// clang-format off
|
|
||||||
#elif DMON_OS_MACOS
|
#elif DMON_OS_MACOS
|
||||||
// FSEvents MacOS backend
|
// FSEvents MacOS backend
|
||||||
typedef struct dmon__fsevent_event {
|
typedef struct dmon__fsevent_event {
|
||||||
|
@ -1346,7 +1289,6 @@ union dmon__cast_userdata {
|
||||||
|
|
||||||
static bool _dmon_init;
|
static bool _dmon_init;
|
||||||
static dmon__state _dmon;
|
static dmon__state _dmon;
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
_DMON_PRIVATE void* dmon__cf_malloc(CFIndex size, CFOptionFlags hints, void* info)
|
_DMON_PRIVATE void* dmon__cf_malloc(CFIndex size, CFOptionFlags hints, void* info)
|
||||||
{
|
{
|
||||||
|
@ -1695,9 +1637,7 @@ DMON_API_IMPL void dmon_unwatch(dmon_watch_id id)
|
||||||
__sync_lock_test_and_set(&_dmon.modify_watches, 0);
|
__sync_lock_test_and_set(&_dmon.modify_watches, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // DMON_IMPL
|
#endif // DMON_IMPL
|
||||||
#endif // __DMON_H__
|
#endif // __DMON_H__
|
||||||
// clang-format on
|
|
||||||
|
|
Loading…
Reference in New Issue