Do not use timeout in dmon linux select
Wait indefinitely in select and wake-up the thread when needed.
This commit is contained in:
parent
44a8dc320b
commit
19ec86d971
|
@ -727,6 +727,8 @@ typedef struct dmon__state {
|
|||
int num_watches;
|
||||
pthread_t thread_handle;
|
||||
pthread_mutex_t mutex;
|
||||
int wait_flag;
|
||||
int wake_event_pipe[2];
|
||||
bool quit;
|
||||
} dmon__state;
|
||||
|
||||
|
@ -1012,29 +1014,39 @@ static void* dmon__thread(void* arg)
|
|||
static uint8_t buff[_DMON_TEMP_BUFFSIZE];
|
||||
struct timespec req = { (time_t)10 / 1000, (long)(10 * 1000000) };
|
||||
struct timespec rem = { 0, 0 };
|
||||
struct timeval timeout;
|
||||
uint64_t usecs_elapsed = 0;
|
||||
|
||||
struct timeval starttm;
|
||||
gettimeofday(&starttm, 0);
|
||||
|
||||
int debug_count = 0;
|
||||
while (!_dmon.quit) {
|
||||
nanosleep(&req, &rem);
|
||||
if (_dmon.num_watches == 0 || pthread_mutex_trylock(&_dmon.mutex) != 0) {
|
||||
if (_dmon.num_watches == 0 || _dmon.wait_flag == 1 || pthread_mutex_trylock(&_dmon.mutex) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create read FD set
|
||||
fd_set rfds;
|
||||
FD_ZERO(&rfds);
|
||||
for (int i = 0; i < _dmon.num_watches; i++) {
|
||||
const int n = _dmon.num_watches;
|
||||
int nfds = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
dmon__watch_state* watch = &_dmon.watches[i];
|
||||
FD_SET(watch->fd, &rfds);
|
||||
if (watch->fd > nfds)
|
||||
nfds = watch->fd;
|
||||
}
|
||||
int wake_fd = _dmon.wake_event_pipe[0];
|
||||
FD_SET(wake_fd, &rfds);
|
||||
if (wake_fd > nfds)
|
||||
nfds = wake_fd;
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 100000;
|
||||
if (select(FD_SETSIZE, &rfds, NULL, NULL, &timeout)) {
|
||||
if (select(nfds + 1, &rfds, NULL, NULL, NULL)) {
|
||||
if (FD_ISSET(wake_fd, &rfds)) {
|
||||
char read_char;
|
||||
read(wake_fd, &read_char, 1);
|
||||
}
|
||||
for (int i = 0; i < _dmon.num_watches; i++) {
|
||||
dmon__watch_state* watch = &_dmon.watches[i];
|
||||
if (FD_ISSET(watch->fd, &rfds)) {
|
||||
|
@ -1084,6 +1096,16 @@ static void* dmon__thread(void* arg)
|
|||
return 0x0;
|
||||
}
|
||||
|
||||
_DMON_PRIVATE void dmon__mutex_wakeup_lock() {
|
||||
_dmon.wait_flag = 1;
|
||||
if (pthread_mutex_trylock(&_dmon.mutex) != 0) {
|
||||
char send_char = 1;
|
||||
write(_dmon.wake_event_pipe[1], &send_char, 1);
|
||||
pthread_mutex_lock(&_dmon.mutex);
|
||||
}
|
||||
_dmon.wait_flag = 0;
|
||||
}
|
||||
|
||||
_DMON_PRIVATE void dmon__unwatch(dmon__watch_state* watch)
|
||||
{
|
||||
close(watch->fd);
|
||||
|
@ -1097,6 +1119,9 @@ DMON_API_IMPL void dmon_init(void)
|
|||
DMON_ASSERT(!_dmon_init);
|
||||
pthread_mutex_init(&_dmon.mutex, NULL);
|
||||
|
||||
_dmon.wait_flag = 0;
|
||||
int ret_pipe = pipe(_dmon.wake_event_pipe);
|
||||
DMON_ASSERT(ret_pipe == 0);
|
||||
int r = pthread_create(&_dmon.thread_handle, NULL, dmon__thread, NULL);
|
||||
_DMON_UNUSED(r);
|
||||
DMON_ASSERT(r == 0 && "pthread_create failed");
|
||||
|
@ -1107,12 +1132,14 @@ DMON_API_IMPL void dmon_deinit(void)
|
|||
{
|
||||
DMON_ASSERT(_dmon_init);
|
||||
_dmon.quit = true;
|
||||
dmon__mutex_wakeup_lock();
|
||||
pthread_join(_dmon.thread_handle, NULL);
|
||||
|
||||
for (int i = 0; i < _dmon.num_watches; i++) {
|
||||
dmon__unwatch(&_dmon.watches[i]);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&_dmon.mutex);
|
||||
pthread_mutex_destroy(&_dmon.mutex);
|
||||
stb_sb_free(_dmon.events);
|
||||
_dmon_init = false;
|
||||
|
@ -1127,7 +1154,7 @@ DMON_API_IMPL dmon_watch_id dmon_watch(const char* rootdir,
|
|||
DMON_ASSERT(watch_cb);
|
||||
DMON_ASSERT(rootdir && rootdir[0]);
|
||||
|
||||
pthread_mutex_lock(&_dmon.mutex);
|
||||
dmon__mutex_wakeup_lock();
|
||||
|
||||
DMON_ASSERT(_dmon.num_watches < DMON_MAX_WATCHES);
|
||||
|
||||
|
@ -1206,7 +1233,7 @@ DMON_API_IMPL void dmon_unwatch(dmon_watch_id id)
|
|||
{
|
||||
DMON_ASSERT(id.id > 0);
|
||||
|
||||
pthread_mutex_lock(&_dmon.mutex);
|
||||
dmon__mutex_wakeup_lock();
|
||||
|
||||
int index = id.id - 1;
|
||||
DMON_ASSERT(index < _dmon.num_watches);
|
||||
|
|
|
@ -42,8 +42,9 @@ DMON_API_IMPL bool dmon_watch_add(dmon_watch_id id, const char* watchdir, dmon_e
|
|||
|
||||
bool skip_lock = pthread_self() == _dmon.thread_handle;
|
||||
|
||||
if (!skip_lock)
|
||||
pthread_mutex_lock(&_dmon.mutex);
|
||||
if (!skip_lock) {
|
||||
dmon__mutex_wakeup_lock();
|
||||
}
|
||||
|
||||
dmon__watch_state* watch = &_dmon.watches[id.id - 1];
|
||||
|
||||
|
@ -115,8 +116,9 @@ DMON_API_IMPL bool dmon_watch_rm(dmon_watch_id id, const char* watchdir)
|
|||
|
||||
bool skip_lock = pthread_self() == _dmon.thread_handle;
|
||||
|
||||
if (!skip_lock)
|
||||
pthread_mutex_lock(&_dmon.mutex);
|
||||
if (!skip_lock) {
|
||||
dmon__mutex_wakeup_lock();
|
||||
}
|
||||
|
||||
dmon__watch_state* watch = &_dmon.watches[id.id - 1];
|
||||
|
||||
|
|
Loading…
Reference in New Issue