summaryrefslogtreecommitdiff
path: root/3rdparty/plibsys/src/psemaphore.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/plibsys/src/psemaphore.h')
-rw-r--r--3rdparty/plibsys/src/psemaphore.h191
1 files changed, 191 insertions, 0 deletions
diff --git a/3rdparty/plibsys/src/psemaphore.h b/3rdparty/plibsys/src/psemaphore.h
new file mode 100644
index 0000000..29fb48e
--- /dev/null
+++ b/3rdparty/plibsys/src/psemaphore.h
@@ -0,0 +1,191 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file psemaphore.h
+ * @brief Semaphore routines
+ * @author Alexander Saprykin
+ *
+ * A semaphore is a synchronization primitive which controls access to shared
+ * data from the concurrently running threads. Unlike a mutex (which is a
+ * particular case of a binary semaphore) it allows concurrent access not to
+ * only the one thread.
+ *
+ * The semaphore has a counter which means the number of available resources
+ * (units). Before entering a critical section a thread must perform the so
+ * called P (acquire) operation: if the counter is positive it decrements the
+ * counter by 1 and continues execution; otherwise the thread is suspended until
+ * the counter becomes positive. Before leaving the critical section the thread
+ * must perform the so called V (release) operation: increments the counter by 1
+ * and wakes up a waiting thread from the queue (if any).
+ *
+ * You can think about the semaphore as a resource controller: the P operation
+ * takes one unit, while the V operation gives one unit back. The thread could
+ * not continue execution without taking a resource unit. By setting the initial
+ * semaphore counter value you can control how much concurrent threads can work
+ * with a shared resource.
+ *
+ * This semaphore implementation is process-wide so you can synchronize not only
+ * the threads. But it makes this IPC primitive (actually like any other IPC
+ * primitive, as well) relatively heavy. Consider using a mutex or a spinlock
+ * instead if you do not need to cross a process boundary.
+ *
+ * A process-wide semaphore is identified by its name across the system, thus it
+ * is also called a named semaphore. Use p_semaphore_new() to open the named
+ * semaphore and p_semaphore_free() to close it.
+ *
+ * Please note the following platform specific differences:
+ *
+ * - Windows doesn't own IPC objects (processes own them), which means that a
+ * semaphore will be removed from the system after the last process or thread
+ * closes it (or after terminating all the processes and threads holding open
+ * semaphore).
+ *
+ * - UNIX systems own IPC objects. Because of that UNIX IPC objects can survive
+ * an application crash: an already used semaphore can be opened in a locked
+ * state and an application can fail into a deadlock or an inconsistent state.
+ * This could happen if you have not closed all the open semaphores explicitly
+ * before terminating the application.
+ *
+ * - IRIX allows to open several instances of a semaphore within the single
+ * process, but it will close the object after the first close call from any of
+ * the threads within the process.
+ *
+ * - AmigaOS has process-wide semaphores without actual tracking of counter,
+ * which means that semaphore behaves the same way as recursive mutex.
+ *
+ * - OpenVMS (as of 8.4 release) has declared prototypes for process-wide named
+ * semaphores but the actual implementation is broken.
+ *
+ * - OS/2 lacks support for process-wide named semaphores.
+ *
+ * - Syllable lacks support for process-wide named semaphores.
+ *
+ * - BeOS lacks support for process-wide named semaphores.
+ *
+ * Use the third argument as #P_SEM_ACCESS_CREATE in p_semaphore_new() to reset
+ * a semaphore value while opening it. This argument is ignored on Windows. You
+ * can also take ownership of the semaphore with p_semaphore_take_ownership() to
+ * explicitly remove it from the system after closing.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PSEMAPHORE_H
+#define PLIBSYS_HEADER_PSEMAPHORE_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+#include <perror.h>
+
+P_BEGIN_DECLS
+
+/** Enum with semaphore creation modes. */
+typedef enum PSemaphoreAccessMode_ {
+ P_SEM_ACCESS_OPEN = 0, /**< Opens an existing semaphore or creates one with a given value. */
+ P_SEM_ACCESS_CREATE = 1 /**< Creates semaphore, resets to a given value if exists. */
+} PSemaphoreAccessMode;
+
+/** Semaphore opaque data structure. */
+typedef struct PSemaphore_ PSemaphore;
+
+/**
+ * @brief Creates a new #PSemaphore object.
+ * @param name Semaphore name.
+ * @param init_val Initial semaphore value.
+ * @param mode Creation mode.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Pointer to a newly created #PSemaphore object in case of success,
+ * NULL otherwise.
+ * @since 0.0.1
+ *
+ * The @a init_val is used only in one of following cases: a semaphore with the
+ * such name doesn't exist, or the semaphore with the such name exists but
+ * @a mode specified as #P_SEM_ACCESS_CREATE (non-Windows platforms only). In
+ * other cases @a init_val is ignored. The @a name is system-wide, so any other
+ * process can open that semaphore passing the same name.
+ */
+P_LIB_API PSemaphore * p_semaphore_new (const pchar *name,
+ pint init_val,
+ PSemaphoreAccessMode mode,
+ PError **error);
+
+/**
+ * @brief Takes ownership of a semaphore.
+ * @param sem Semaphore to take ownership.
+ * @since 0.0.1
+ *
+ * If you take ownership of a semaphore object, p_semaphore_free() will try to
+ * completely unlink it and remove from the system. This is useful on UNIX
+ * systems where the semaphore can survive an application crash. On the Windows
+ * platform this call has no effect.
+ *
+ * The common usage of this call is upon application startup to ensure that the
+ * semaphore from the previous crash will be unlinked from the system. To do
+ * that, call p_semaphore_new(), take ownership of the semaphore object and
+ * remove it with the p_semaphore_free() call. After that, create it again.
+ *
+ * You can also do the same thing upon semaphore creation passing
+ * #P_SEM_ACCESS_CREATE to p_semaphore_new(). The only difference is that you
+ * should already know whether this semaphore object is from the previous crash
+ * or not.
+ */
+P_LIB_API void p_semaphore_take_ownership (PSemaphore *sem);
+
+/**
+ * @brief Acquires (P operation) a semaphore.
+ * @param sem #PSemaphore to acquire.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_semaphore_acquire (PSemaphore *sem,
+ PError **error);
+
+/**
+ * @brief Releases (V operation) a semaphore.
+ * @param sem #PSemaphore to release.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_semaphore_release (PSemaphore *sem,
+ PError **error);
+
+/**
+ * @brief Frees #PSemaphore object.
+ * @param sem #PSemaphore to free.
+ * @since 0.0.1
+ *
+ * It doesn't release an acquired semaphore, be careful to not to make a
+ * deadlock while removing the acquired semaphore.
+ */
+P_LIB_API void p_semaphore_free (PSemaphore *sem);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PSEMAPHORE_H */