summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'base/gxsync.c')
-rw-r--r--base/gxsync.c151
1 files changed, 151 insertions, 0 deletions
diff --git a/base/gxsync.c b/base/gxsync.c
new file mode 100644
index 00000000..8bb30ef1
--- /dev/null
+++ b/base/gxsync.c
@@ -0,0 +1,151 @@
+/* Copyright (C) 2001-2019 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
+ CA 94945, U.S.A., +1(415)492-9861, for further information.
+*/
+
+
+/* Interface to platform-based synchronization primitives */
+
+/* Initial version 2/1/98 by John Desrosiers (soho@crl.com) */
+
+#include "memory_.h"
+#include "gx.h"
+#include "gserrors.h"
+#include "gsmemory.h"
+#include "gxsync.h"
+
+/* This module abstracts the platform-specific synchronization primitives. */
+/* Since these routines will see heavy use, performance is important. */
+
+/* ----- Semaphore interface ----- */
+/* These have the usual queued, counting semaphore semantics: at init time, */
+/* the event count is set to 0 ('wait' will wait until 1st signal). */
+
+/* Allocate & initialize a semaphore */
+gx_semaphore_t * /* returns a new semaphore, 0 if error */
+gx_semaphore_alloc(
+ gs_memory_t * memory /* memory allocator to use */
+)
+{
+ gx_semaphore_t *sema;
+
+ /* sizeof decl'd sema struct, minus semaphore placeholder's size, + actual semaphore size */
+ unsigned semaSizeof
+ = sizeof(*sema) - sizeof(sema->native) + gp_semaphore_sizeof();
+
+ if (gp_semaphore_open(0) == 0) /* see if gp_semaphores are movable */
+ /* movable */
+ sema = (gx_semaphore_t *) gs_alloc_bytes(memory, semaSizeof,
+ "gx_semaphore (create)");
+ else
+ /* unmovable */
+ sema = (gx_semaphore_t *) gs_alloc_bytes_immovable(memory, semaSizeof,
+ "gx_semaphore (create)");
+ if (sema == 0)
+ return 0;
+
+ /* Make sema remember which allocator was used to allocate it */
+ sema->memory = memory;
+
+ if (gp_semaphore_open(&sema->native) < 0) {
+ gs_free_object(memory, sema, "gx_semaphore (alloc)");
+ return 0;
+ }
+ return sema;
+}
+
+/* Deinit & free a semaphore */
+void
+gx_semaphore_free(
+ gx_semaphore_t * sema /* semaphore to delete */
+)
+{
+ if (sema) {
+ gp_semaphore_close(&sema->native);
+ gs_free_object(sema->memory, sema, "gx_semaphore (free)");
+ }
+}
+
+gx_semaphore_t *(gx_semaphore_label)(gx_semaphore_t *sema, const char *name)
+{
+ (void)name;
+ if (sema)
+ gp_semaphore_label(&sema->native, name);
+ return sema;
+}
+
+/* Macros defined in gxsync.h, but redefined here so compiler chex consistency */
+#define gx_semaphore_wait(sema) gp_semaphore_wait(&(sema)->native)
+#define gx_semaphore_signal(sema) gp_semaphore_signal(&(sema)->native)
+
+/* ----- Monitor interface ----- */
+/* These have the usual monitor semantics: at init time, */
+/* the event count is set to 1 (1st 'enter' succeeds immediately). */
+
+/* Allocate & Init a monitor */
+gx_monitor_t * /* returns a new monitor, 0 if error */
+gx_monitor_alloc(
+ gs_memory_t * memory /* memory allocator to use */
+)
+{
+ gx_monitor_t *mon;
+
+ /* sizeof decl'd mon struct, minus monitor placeholder's size, + actual monitor size */
+ unsigned monSizeof
+ = sizeof(*mon) - sizeof(mon->native) + gp_monitor_sizeof();
+
+ if (gp_monitor_open(0) == 0) /* see if gp_monitors are movable */
+ /* movable */
+ mon = (gx_monitor_t *) gs_alloc_bytes(memory, monSizeof,
+ "gx_monitor (create)");
+ else
+ /* unmovable */
+ mon = (gx_monitor_t *) gs_alloc_bytes_immovable(memory, monSizeof,
+ "gx_monitor (create)");
+ if (mon == 0)
+ return 0;
+
+ /* Make monitor remember which allocator was used to allocate it */
+ mon->memory = memory;
+
+ if (gp_monitor_open(&mon->native) < 0) {
+ gs_free_object(memory, mon, "gx_monitor (alloc)");
+ return 0;
+ }
+ return mon;
+}
+
+/* Dnit & free a monitor */
+void
+gx_monitor_free(
+ gx_monitor_t * mon /* monitor to delete */
+)
+{
+ if (mon) {
+ gp_monitor_close(&mon->native);
+ gs_free_object(mon->memory, mon, "gx_monitor (free)");
+ }
+}
+
+gx_monitor_t *
+(gx_monitor_label)(gx_monitor_t *mon, const char *name)
+{
+ (void)name;
+ if (mon)
+ gp_monitor_label(&mon->native, name);
+ return mon;
+}
+
+/* Macros defined in gxsync.h, but redefined here so compiler chex consistency */
+#define gx_monitor_enter(sema) gp_monitor_enter(&(sema)->native)
+#define gx_monitor_leave(sema) gp_monitor_leave(&(sema)->native)