summaryrefslogtreecommitdiff
path: root/src/libstrongswan/threading
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2015-06-01 14:46:30 +0200
committerYves-Alexis Perez <corsac@debian.org>2015-06-01 14:46:30 +0200
commitfc556ec2bc92a9d476c11406fad2c33db8bf7cb0 (patch)
tree7360889e50de867d72741213d534a756c73902c8 /src/libstrongswan/threading
parent83b8aebb19fe6e49e13a05d4e8f5ab9a06177642 (diff)
downloadvyos-strongswan-fc556ec2bc92a9d476c11406fad2c33db8bf7cb0.tar.gz
vyos-strongswan-fc556ec2bc92a9d476c11406fad2c33db8bf7cb0.zip
Imported Upstream version 5.3.1
Diffstat (limited to 'src/libstrongswan/threading')
-rw-r--r--src/libstrongswan/threading/thread.c39
-rw-r--r--src/libstrongswan/threading/thread.h10
-rw-r--r--src/libstrongswan/threading/windows/thread.c20
3 files changed, 51 insertions, 18 deletions
diff --git a/src/libstrongswan/threading/thread.c b/src/libstrongswan/threading/thread.c
index 593f44a44..7a243e826 100644
--- a/src/libstrongswan/threading/thread.c
+++ b/src/libstrongswan/threading/thread.c
@@ -16,7 +16,6 @@
#define _GNU_SOURCE
#include <pthread.h>
#include <signal.h>
-#include <semaphore.h>
#ifdef HAVE_GETTID
#include <sys/types.h>
@@ -79,11 +78,6 @@ struct private_thread_t {
mutex_t *mutex;
/**
- * Semaphore used to sync the creation/start of the thread.
- */
- sem_t created;
-
- /**
* TRUE if this thread has been detached or joined, i.e. can be cleaned
* up after terminating.
*/
@@ -160,7 +154,6 @@ static void thread_destroy(private_thread_t *this)
this->cleanup_handlers->destroy(this->cleanup_handlers);
this->mutex->unlock(this->mutex);
this->mutex->destroy(this->mutex);
- sem_destroy(&this->created);
free(this);
}
@@ -263,7 +256,6 @@ static private_thread_t *thread_create_internal()
.cleanup_handlers = linked_list_create(),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
);
- sem_init(&this->created, FALSE, 0);
return this;
}
@@ -292,7 +284,6 @@ static void *thread_main(private_thread_t *this)
{
void *res;
- sem_wait(&this->created);
current_thread->set(current_thread, this);
pthread_cleanup_push((thread_cleanup_t)thread_cleanup, this);
@@ -324,6 +315,10 @@ thread_t *thread_create(thread_main_t main, void *arg)
this->main = main;
this->arg = arg;
+ id_mutex->lock(id_mutex);
+ this->id = next_id++;
+ id_mutex->unlock(id_mutex);
+
if (pthread_create(&this->thread_id, NULL, (void*)thread_main, this) != 0)
{
DBG1(DBG_LIB, "failed to create thread!");
@@ -331,10 +326,6 @@ thread_t *thread_create(thread_main_t main, void *arg)
thread_destroy(this);
return NULL;
}
- id_mutex->lock(id_mutex);
- this->id = next_id++;
- id_mutex->unlock(id_mutex);
- sem_post(&this->created);
return &this->public;
}
@@ -383,9 +374,7 @@ void thread_cleanup_push(thread_cleanup_t cleanup, void *arg)
.arg = arg,
);
- this->mutex->lock(this->mutex);
this->cleanup_handlers->insert_last(this->cleanup_handlers, handler);
- this->mutex->unlock(this->mutex);
}
/**
@@ -396,15 +385,12 @@ void thread_cleanup_pop(bool execute)
private_thread_t *this = (private_thread_t*)thread_current();
cleanup_handler_t *handler;
- this->mutex->lock(this->mutex);
if (this->cleanup_handlers->remove_last(this->cleanup_handlers,
(void**)&handler) != SUCCESS)
{
- this->mutex->unlock(this->mutex);
DBG1(DBG_LIB, "!!! THREAD CLEANUP ERROR !!!");
return;
}
- this->mutex->unlock(this->mutex);
if (execute)
{
@@ -416,6 +402,23 @@ void thread_cleanup_pop(bool execute)
/**
* Described in header.
*/
+void thread_cleanup_popall()
+{
+ private_thread_t *this = (private_thread_t*)thread_current();
+ cleanup_handler_t *handler;
+
+ while (this->cleanup_handlers->get_count(this->cleanup_handlers))
+ {
+ this->cleanup_handlers->remove_last(this->cleanup_handlers,
+ (void**)&handler);
+ handler->cleanup(handler->arg);
+ free(handler);
+ }
+}
+
+/**
+ * Described in header.
+ */
bool thread_cancelability(bool enable)
{
#ifdef HAVE_PTHREAD_CANCEL
diff --git a/src/libstrongswan/threading/thread.h b/src/libstrongswan/threading/thread.h
index 38275541e..c24772839 100644
--- a/src/libstrongswan/threading/thread.h
+++ b/src/libstrongswan/threading/thread.h
@@ -124,6 +124,16 @@ void thread_cleanup_push(thread_cleanup_t cleanup, void *arg);
void thread_cleanup_pop(bool execute);
/**
+ * Pop and execute all cleanup handlers in reverse order of registration.
+ *
+ * This function is for very special purposes only, where the caller exactly
+ * knows which cleanup handlers have been pushed. For regular use, a caller
+ * should thread_cleanup_pop() exactly the number of handlers it pushed
+ * using thread_cleanup_push().
+ */
+void thread_cleanup_popall();
+
+/**
* Enable or disable the cancelability of the current thread. The current
* value is returned.
*
diff --git a/src/libstrongswan/threading/windows/thread.c b/src/libstrongswan/threading/windows/thread.c
index e76758f8c..610524722 100644
--- a/src/libstrongswan/threading/windows/thread.c
+++ b/src/libstrongswan/threading/windows/thread.c
@@ -562,6 +562,26 @@ void thread_cleanup_pop(bool execute)
/**
* Described in header.
*/
+void thread_cleanup_popall()
+{
+ private_thread_t *this;
+ cleanup_t cleanup = {};
+ bool old;
+
+ this = get_current_thread();
+ while (array_count(this->cleanup))
+ {
+ old = set_leak_detective(FALSE);
+ array_remove(this->cleanup, -1, &cleanup);
+ set_leak_detective(old);
+
+ cleanup.cb(cleanup.arg);
+ }
+}
+
+/**
+ * Described in header.
+ */
bool thread_cancelability(bool enable)
{
private_thread_t *this;