summaryrefslogtreecommitdiff
path: root/src/thread.h
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@opera.com>2015-07-13 13:04:24 +0200
committerJoel Klinghed <the_jk@opera.com>2015-07-13 13:04:24 +0200
commit1d8af5a018282dc6a93b9ed7c87d9d2f87287b14 (patch)
treec47c19f7c27fd1774d1455b088eb207c611d30ed /src/thread.h
parent59709e4cb30f2ff8666522d5b758731ab618adbc (diff)
Copy the dependencies from sawmill project
Diffstat (limited to 'src/thread.h')
-rw-r--r--src/thread.h266
1 files changed, 266 insertions, 0 deletions
diff --git a/src/thread.h b/src/thread.h
new file mode 100644
index 0000000..c0a21b0
--- /dev/null
+++ b/src/thread.h
@@ -0,0 +1,266 @@
+/**
+ * \file thread.h
+ * A collection of thread methods.
+ */
+
+#ifndef THREAD_H
+#define THREAD_H
+
+#include "timespec.h"
+
+#if HAVE_PTHREAD
+#include <pthread.h>
+/**
+ * Opaque type defining an once variable.
+ */
+typedef pthread_once_t thread_once_t;
+/**
+ * Init value for an once variable
+ */
+#define THREAD_ONCE_INIT PTHREAD_ONCE_INIT
+#else
+# error missing thread_once_t implementation
+#endif
+
+/**
+ * Opaque type defining a joinable thread.
+ */
+typedef struct thread_t thread_t;
+/**
+ * Opaque type defining an id.
+ */
+typedef struct thread_id_t thread_id_t;
+/**
+ * Opaque type defining a lock.
+ */
+typedef struct thread_lock_t thread_lock_t;
+/**
+ * Opaque type defining a conditional.
+ */
+typedef struct thread_cond_t thread_cond_t;
+/**
+ * Opaque type defining a thread local variable.
+ */
+typedef struct thread_data_t thread_data_t;
+
+/**
+ * Signature or function type for a thread run method.
+ * A thread run method is the thread main() if you will.
+ * When the method returns the thread is terminated.
+ * @param userdata argument given when starting the thread
+ */
+typedef void* (* thread_run_t)(void* userdata);
+
+/**
+ * Create and start a thread.
+ * @param run thread run method
+ * @param userdata argument to run method, may not be NULL
+ * @return true if thread was started without errors, may be NULL
+ */
+NONULL_ARGS(1)
+bool thread_new(thread_run_t run, void* userdata);
+
+/**
+ * Create and start a joinable thread.
+ * Must call thread_join to free thread resources.
+ * @param run thread run method, may not be NULL
+ * @param userdata argument to run method, may be NULL
+ * @return NULL in case of error
+ */
+NONULL_ARGS(1)
+MALLOC thread_t* thread_joinable_new(thread_run_t run, void* userdata);
+
+/**
+ * Wait for a joinable thread to exit, free it and return the result.
+ * @param thread result from call to thread_joinable_new, may not be NULL
+ * @return result of the thread run method
+ */
+NONULL void* thread_join(thread_t* thread);
+
+
+/**
+ * Create a unique thread id pointing to the given or current thread.
+ * If no thread is given then a id for the current running thread is returned.
+ * Returns NULL in case of error.
+ * @param thread result from call to thread_joinable_new or NULL
+ * @return a new thread id
+ */
+MALLOC thread_id_t* thread_id_new(thread_t* thread);
+
+/**
+ * Free a thread id.
+ * @param id thread id to free, may be NULL
+ */
+void thread_id_free(thread_id_t* id);
+
+/**
+ * Return true if the current thread matches the thread id.
+ * @param id thread id to check, may not be NULL
+ * @return true if the id matches the current thread
+ */
+NONULL bool thread_id_is_current(thread_id_t* id);
+
+/**
+ * Thread yield, give another thread the chance to run.
+ */
+void thread_yield(void);
+
+/**
+ * Create a possibly non-recursive lock (mutex).
+ * Returns NULL in case of error.
+ * @return a new thread lock
+ */
+MALLOC thread_lock_t* thread_lock_new(void);
+
+/**
+ * Create a recursive lock (mutex).
+ * Returns NULL in case of error.
+ * @return a new thread lock
+ */
+MALLOC thread_lock_t* thread_lock_recursive_new(void);
+
+/**
+ * Free a lock.
+ * The lock must not have a owner when freed or undefined behaviour will ensue.
+ * @param lock lock to free, may be NULL
+ */
+void thread_lock_free(thread_lock_t* lock);
+
+/**
+ * Take ownership of the lock.
+ * If another thread has ownership of the lock, wait until that thread releases
+ * the lock.
+ * If the current thread already has ownership of the lock and the lock is
+ * recursive the current thread now owns the lock twice.
+ * Undefined behavior (abort or deadlock probably) if the lock isn't recursive
+ * and the current thread already has ownership.
+ * @param lock lock to take ownership of
+ */
+NONULL void thread_lock_lock(thread_lock_t* lock);
+/**
+ * Release ownership of the lock.
+ * Only call if the current thread has one or more ownerships of the lock.
+ * If the lock is recursive only one ownership is released.
+ * Undefined behaviour (abort or deadlock probably) if the lock isn't owned
+ * by the current thread.
+ * @param lock lock to release
+ */
+NONULL void thread_lock_unlock(thread_lock_t* lock);
+
+/**
+ * Create a conditional. Conditionals can be used to signal other threads
+ * that a condition has been fulfilled if they were waiting for it.
+ * Returns NULL in case of error.
+ * @return new conditional
+ */
+MALLOC thread_cond_t* thread_cond_new(void);
+/**
+ * Free a conditional. No thread may be waiting on the conditional or undefined
+ * behaviour will ensue.
+ * @param cond conditional to free, may be NULL
+ */
+void thread_cond_free(thread_cond_t* cond);
+
+/**
+ * Setup the current thread to wait for the condition to be signalled.
+ * The lock must be owned by the current thread before calling and will be
+ * release while the current thread is waiting but reclaimed upon return.
+ * @param cond conditonal to wait upon, may not be NULL
+ * @param lock lock to release and retake ownership of, may not be NULL
+ */
+NONULL void thread_cond_wait(thread_cond_t* cond, thread_lock_t* lock);
+
+/**
+ * Setup the current thread to wait for the condition to be signalled until
+ * abstime.
+ * The lock must be owned by the current thread before calling and will be
+ * release while the current thread is waiting but reclaimed upon return.
+ * Use thread_abstime() to fill out the abstime.
+ * @param cond conditonal to wait upon, may not be NULL
+ * @param lock lock to release and retake ownership of, may not be NULL
+ * @param abstime time when to give up and return, may not be NULL
+ * @return true if the condition was signalled, false if it timed out
+ */
+NONULL bool thread_cond_timedwait(thread_cond_t* cond, thread_lock_t* lock,
+ const struct timespec *abstime);
+
+/**
+ * Signal one thread that is currently waiting on the given condition.
+ * The selected thread (which one is random) will be woken up.
+ * The calling thread may or may not own the lock when calling
+ * thread_cond_signal but the signalled thread will not wake up before the lock
+ * is released.
+ * @param cond conditional to signal, may not be NULL
+ */
+NONULL void thread_cond_signal(thread_cond_t* cond);
+
+/**
+ * Signal all threads that is currently waiting on the given condition.
+ * All waiting threads will be woken up but only one may get ownership
+ * of the lock.
+ * The calling thread may or may not own the lock when calling
+ * thread_cond_broadcast but the signalled threads will not wake up before the
+ * lock is released.
+ * @param cond conditional to signal, may not be NULL
+ */
+NONULL void thread_cond_broadcast(thread_cond_t* cond);
+
+/**
+ * Get the current absolute time and add a certain number of milliseconds
+ * to it. To be used with thread_cond_timedwait.
+ * @param abstime struct to file with the current absolute time and the
+ * extra milliseconds.
+ * @param add_ms milliseconds to add to the current absolute time
+ */
+NONULL void thread_abstime(struct timespec *abstime, unsigned long add_ms);
+
+/**
+ * Function type for a thread local variable value destructor
+ */
+typedef void (* thread_data_value_free_t)(void *value);
+
+/**
+ * Create a thread local variable.
+ * Returns NULL in case of error.
+ * @param free_value destructor for set non-null value at thread exit,
+ * may be NULL
+ * @return new thread local variable or NULL
+ */
+MALLOC thread_data_t *thread_data_new(thread_data_value_free_t free_value);
+
+/**
+ * Free a thread local variable.
+ * Does not call any destructor.
+ * @param data thread local variable to free, may be NULL
+ */
+void thread_data_free(thread_data_t *data);
+
+/**
+ * Get the thread local value of the variable.
+ * @param data thread local variable, may not be NULL
+ * @return thread local value for variable
+ */
+NONULL void *thread_data_value(thread_data_t *data);
+
+/**
+ * Set thread local value for variable.
+ * @param data thread local variable, may not be NULL
+ * @param value new value, may be NULL
+ */
+NONULL_ARGS(1)
+void thread_data_set(thread_data_t *data, void *value);
+
+/**
+ * Function type for a thread once method
+ */
+typedef void (* thread_run_once_t)(void);
+
+/**
+ * The first thread calling this method will run "run". Any subsequent thread
+ * calling thread_once for the same once variable will do nothing.
+ * @param once address to a static once variable, may not be NULL
+ * @param run method to run if this is the first thread, may not be NULL
+ */
+NONULL void thread_once(thread_once_t *once, thread_run_once_t run);
+
+#endif /* THREAD_H */