diff options
Diffstat (limited to 'src/libstrongswan/processing/watcher.c')
-rw-r--r-- | src/libstrongswan/processing/watcher.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/src/libstrongswan/processing/watcher.c b/src/libstrongswan/processing/watcher.c index cc3c3a788..09905646c 100644 --- a/src/libstrongswan/processing/watcher.c +++ b/src/libstrongswan/processing/watcher.c @@ -50,6 +50,11 @@ struct private_watcher_t { bool pending; /** + * Is watcher running? + */ + bool running; + + /** * Lock to access FD list */ mutex_t *mutex; @@ -225,6 +230,7 @@ static void activate_all(private_watcher_t *this) entry->in_callback = 0; } enumerator->destroy(enumerator); + this->running = FALSE; this->condvar->broadcast(this->condvar); this->mutex->unlock(this->mutex); } @@ -238,6 +244,7 @@ static job_requeue_t watch(private_watcher_t *this) entry_t *entry; fd_set rd, wr, ex; int maxfd = 0, res; + bool rebuild = FALSE; FD_ZERO(&rd); FD_ZERO(&wr); @@ -282,7 +289,7 @@ static job_requeue_t watch(private_watcher_t *this) enumerator->destroy(enumerator); this->mutex->unlock(this->mutex); - while (TRUE) + while (!rebuild) { char buf[1]; bool old; @@ -308,6 +315,11 @@ static job_requeue_t watch(private_watcher_t *this) enumerator = this->fds->create_enumerator(this->fds); while (enumerator->enumerate(enumerator, &entry)) { + if (entry->in_callback) + { + rebuild = TRUE; + break; + } if (FD_ISSET(entry->fd, &rd) && (entry->events & WATCHER_READ)) { DBG2(DBG_JOB, "watched FD %d ready to read", entry->fd); @@ -347,6 +359,7 @@ static job_requeue_t watch(private_watcher_t *this) return JOB_REQUEUE_DIRECT; } } + return JOB_REQUEUE_DIRECT; } METHOD(watcher_t, add, void, @@ -366,6 +379,7 @@ METHOD(watcher_t, add, void, this->fds->insert_last(this->fds, entry); if (this->fds->get_count(this->fds) == 1) { + this->running = TRUE; lib->processor->queue_job(lib->processor, (job_t*)callback_job_create_with_prio((void*)watch, this, NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL)); @@ -393,7 +407,7 @@ METHOD(watcher_t, remove_, void, { if (entry->fd == fd) { - if (entry->in_callback) + if (this->running && entry->in_callback) { is_in_callback = TRUE; break; |