aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstrongswan/processing/watcher.c
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2013-07-01 18:38:42 +0200
committerMartin Willi <martin@revosec.ch>2013-07-18 16:00:29 +0200
commita0e3a7363f0f0c2f1189358dd6670b05d59ede70 (patch)
treed49f1b4f1f9e8f600ddb8541f98ba3063cf69100 /src/libstrongswan/processing/watcher.c
parenta558ba16f314d250ef62a593e66e263123a0e9a3 (diff)
downloadstrongswan-a0e3a7363f0f0c2f1189358dd6670b05d59ede70.tar.bz2
strongswan-a0e3a7363f0f0c2f1189358dd6670b05d59ede70.tar.xz
watcher: unregister a watcher FD if its thread gets cancelled
Diffstat (limited to 'src/libstrongswan/processing/watcher.c')
-rw-r--r--src/libstrongswan/processing/watcher.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/libstrongswan/processing/watcher.c b/src/libstrongswan/processing/watcher.c
index ff3e11649..84a870f2c 100644
--- a/src/libstrongswan/processing/watcher.c
+++ b/src/libstrongswan/processing/watcher.c
@@ -106,12 +106,25 @@ static void update(private_watcher_t *this)
}
}
+/**
+ * Cleanup function if callback gets cancelled
+ */
+static void unregister(notify_data_t *data)
+{
+ /* if a thread processing a callback gets cancelled, we mark the entry
+ * as cancelled, like the callback would return FALSE. This is required
+ * to not queue this watcher again if all threads have been gone. */
+ data->keep = FALSE;
+}
+
/**
* Execute callback of registered FD, asynchronous
*/
static job_requeue_t notify_async(notify_data_t *data)
{
+ thread_cleanup_push((void*)unregister, data);
data->keep = data->cb(data->data, data->fd, data->event);
+ thread_cleanup_pop(FALSE);
return JOB_REQUEUE_NONE;
}