watcher: Avoid logging on level 1 while holding the mutex
This could be problematic in case loggers in some way rely on watcher_t themselves. This particular log message should rarely occur if at all, but still avoid holding the mutex.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Tobias Brunner
|
* Copyright (C) 2016-2023 Tobias Brunner
|
||||||
* Copyright (C) 2013 Martin Willi
|
* Copyright (C) 2013 Martin Willi
|
||||||
*
|
*
|
||||||
* Copyright (C) secunet Security Networks AG
|
* Copyright (C) secunet Security Networks AG
|
||||||
@@ -168,20 +168,27 @@ typedef struct {
|
|||||||
} notify_data_t;
|
} notify_data_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify watcher thread about changes
|
* Notify watcher thread about changes and unlock mutex
|
||||||
*/
|
*/
|
||||||
static void update(private_watcher_t *this)
|
static void update_and_unlock(private_watcher_t *this)
|
||||||
{
|
{
|
||||||
char buf[1] = { 'u' };
|
char buf[1] = { 'u' };
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
this->pending = TRUE;
|
this->pending = TRUE;
|
||||||
if (this->notify[1] != -1)
|
if (this->notify[1] != -1)
|
||||||
{
|
{
|
||||||
if (write(this->notify[1], buf, sizeof(buf)) == -1)
|
if (write(this->notify[1], buf, sizeof(buf)) == -1)
|
||||||
{
|
{
|
||||||
DBG1(DBG_JOB, "notifying watcher failed: %s", strerror(errno));
|
error = errno;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
DBG1(DBG_JOB, "notifying watcher failed: %s", strerror(error));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -233,9 +240,8 @@ static void notify_end(notify_data_t *data)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
update(this);
|
|
||||||
this->condvar->broadcast(this->condvar);
|
this->condvar->broadcast(this->condvar);
|
||||||
this->mutex->unlock(this->mutex);
|
update_and_unlock(this);
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
@@ -258,7 +264,7 @@ static void notify(private_watcher_t *this, entry_t *entry,
|
|||||||
.this = this,
|
.this = this,
|
||||||
);
|
);
|
||||||
|
|
||||||
/* deactivate entry, so we can select() other FDs even if the async
|
/* deactivate entry, so we can poll() other FDs even if the async
|
||||||
* processing did not handle the event yet */
|
* processing did not handle the event yet */
|
||||||
entry->in_callback++;
|
entry->in_callback++;
|
||||||
|
|
||||||
@@ -497,15 +503,16 @@ METHOD(watcher_t, add, void,
|
|||||||
if (this->state == WATCHER_STOPPED)
|
if (this->state == WATCHER_STOPPED)
|
||||||
{
|
{
|
||||||
this->state = WATCHER_QUEUED;
|
this->state = WATCHER_QUEUED;
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
|
|
||||||
lib->processor->queue_job(lib->processor,
|
lib->processor->queue_job(lib->processor,
|
||||||
(job_t*)callback_job_create_with_prio((void*)watch, this,
|
(job_t*)callback_job_create_with_prio((void*)watch, this,
|
||||||
NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL));
|
NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
update(this);
|
update_and_unlock(this);
|
||||||
}
|
}
|
||||||
this->mutex->unlock(this->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(watcher_t, remove_, void,
|
METHOD(watcher_t, remove_, void,
|
||||||
@@ -544,9 +551,12 @@ METHOD(watcher_t, remove_, void,
|
|||||||
}
|
}
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
update(this);
|
update_and_unlock(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
}
|
}
|
||||||
this->mutex->unlock(this->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(watcher_t, get_state, watcher_state_t,
|
METHOD(watcher_t, get_state, watcher_state_t,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ typedef enum watcher_state_t watcher_state_t;
|
|||||||
* re-enable the event, while the data read can be processed in another
|
* re-enable the event, while the data read can be processed in another
|
||||||
* asynchronous job.
|
* asynchronous job.
|
||||||
*
|
*
|
||||||
* On Linux, even if select() marks an FD as "ready", a subsequent read/write
|
* On Linux, even if poll() marks an FD as "ready", a subsequent read/write
|
||||||
* can block. It is therefore highly recommended to use non-blocking I/O
|
* can block. It is therefore highly recommended to use non-blocking I/O
|
||||||
* and handle EAGAIN/EWOULDBLOCK gracefully.
|
* and handle EAGAIN/EWOULDBLOCK gracefully.
|
||||||
*
|
*
|
||||||
@@ -71,7 +71,7 @@ enum watcher_state_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Watch multiple file descriptors using select().
|
* Watch multiple file descriptors using poll().
|
||||||
*/
|
*/
|
||||||
struct watcher_t {
|
struct watcher_t {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user