summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Wilhelmi <wilhelmi@src.gnome.org>1998-12-11 14:41:31 +0000
committerSebastian Wilhelmi <wilhelmi@src.gnome.org>1998-12-11 14:41:31 +0000
commitff713e59ed3c73b4f6bb6b14a32178ef636fc193 (patch)
tree8a6bced829fdaf5386fc1603211e53fc43d5b90e
parent7589569f13339dda58d216ad362e24939b0d50ae (diff)
downloadglib-threads.tar.gz
forgot to add gthread/gthread-nspr.cglib-threads
forgot to add gthread/gthread-nspr.c
-rw-r--r--gthread/gthread-nspr.c218
1 files changed, 218 insertions, 0 deletions
diff --git a/gthread/gthread-nspr.c b/gthread/gthread-nspr.c
new file mode 100644
index 000000000..77672e5f0
--- /dev/null
+++ b/gthread/gthread-nspr.c
@@ -0,0 +1,218 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gthread.c: nspr thread system implementation
+ * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * MT safe
+ */
+
+#include <prpdce.h>
+#include <prthread.h>
+#include <stdlib.h>
+
+#ifdef G_DISABLE_ASSERT
+
+#define STDERR_ASSERT(expr)
+
+#else /* G_DISABLE_ASSERT */
+
+#define STDERR_ASSERT(expr) G_STMT_START{ \
+ if (!(expr)) \
+ g_log (G_LOG_DOMAIN, \
+ G_LOG_LEVEL_ERROR, \
+ "file %s: line %d: assertion failed: (%s)", \
+ __FILE__, \
+ __LINE__, \
+ #expr); }G_STMT_END
+
+#endif /* G_DISABLE_ASSERT */
+
+/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
+ functions from gmem.c and gmessages.c; */
+
+static gboolean
+g_mutex_trylock_nspr_impl (GMutex * mutex)
+{
+ PRStatus status = PRP_TryLock ((PRLock *) mutex);
+ if (status == PR_SUCCESS)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+g_cond_wait_nspr_impl (GCond * cond,
+ GMutex * entered_mutex)
+{
+ PRStatus status = PRP_NakedWait ((PRCondVar *) cond,
+ (PRLock *) entered_mutex,
+ PR_INTERVAL_NO_TIMEOUT);
+ g_assert (status == PR_SUCCESS);
+}
+
+#define G_MICROSEC 1000000
+
+static gboolean
+g_cond_timed_wait_nspr_impl (GCond * cond,
+ GMutex * entered_mutex,
+ GTimeVal * abs_time)
+{
+ PRStatus status;
+ PRIntervalTime interval;
+ GTimeVal current_time;
+ glong microsecs;
+
+ g_return_val_if_fail (cond != NULL, FALSE);
+ g_return_val_if_fail (entered_mutex != NULL, FALSE);
+
+ g_get_current_time (&current_time);
+
+ if (abs_time->tv_sec < current_time.tv_sec ||
+ (abs_time->tv_sec == current_time.tv_sec &&
+ abs_time->tv_usec < current_time.tv_usec))
+ return FALSE;
+
+ interval = PR_SecondsToInterval (abs_time->tv_sec - current_time.tv_sec);
+ microsecs = abs_time->tv_usec - current_time.tv_usec;
+ if (microsecs < 0)
+ interval -= PR_MicrosecondsToInterval (-microsecs);
+ else
+ interval += PR_MicrosecondsToInterval (microsecs);
+
+ status = PRP_NakedWait ((PRCondVar *) cond, (PRLock *) entered_mutex,
+ interval);
+
+ g_assert (status == PR_SUCCESS);
+
+ g_get_current_time (&current_time);
+
+ if (abs_time->tv_sec < current_time.tv_sec ||
+ (abs_time->tv_sec == current_time.tv_sec &&
+ abs_time->tv_usec < current_time.tv_usec))
+ return FALSE;
+ return TRUE;
+}
+
+typedef struct _GPrivateNSPRData GPrivateNSPRData;
+struct _GPrivateNSPRData
+ {
+ gpointer data;
+ GDestroyNotify destructor;
+ };
+
+typedef struct _GPrivateNSPR GPrivateNSPR;
+struct _GPrivateNSPR
+ {
+ PRUintn private;
+ GDestroyNotify destructor;
+ };
+
+static GPrivateNSPRData *
+g_private_nspr_data_constructor (GDestroyNotify destructor, gpointer data)
+{
+ /* we can not use g_new and friends, as they might use private data by
+ themself */
+ GPrivateNSPRData *private = malloc (sizeof (GPrivateNSPRData));
+ g_assert (private);
+ private->data = data;
+ private->destructor = destructor;
+
+ return private;
+}
+
+static void
+g_private_nspr_data_destructor (gpointer data)
+{
+ GPrivateNSPRData *private = data;
+ if (private->destructor && private->data)
+ (*private->destructor) (private->data);
+ free (private);
+}
+
+static GPrivate *
+g_private_new_nspr_impl (GDestroyNotify destructor)
+{
+ GPrivateNSPR *result = g_new (GPrivateNSPR, 1);
+ PRStatus status = PR_NewThreadPrivateIndex (&result->private,
+ g_private_nspr_data_destructor);
+ g_assert (status == PR_SUCCESS);
+
+ result->destructor = destructor;
+ return (GPrivate *) result;
+}
+
+/* NOTE: the functions g_private_get and g_private_set may not use
+ functions from gmem.c and gmessages.c */
+
+static GPrivateNSPRData *
+g_private_nspr_data_get (GPrivateNSPR * private)
+{
+ GPrivateNSPRData *data;
+
+ STDERR_ASSERT (private);
+
+ data = PR_GetThreadPrivate (private->private);
+ if (!data)
+ {
+ data = g_private_nspr_data_constructor (private->destructor, NULL);
+ STDERR_ASSERT (PR_SetThreadPrivate (private->private, data)
+ == PR_SUCCESS);
+ }
+
+ return data;
+}
+
+static void
+g_private_set_nspr_impl (GPrivate * private, gpointer value)
+{
+ if (!private)
+ return;
+
+ g_private_nspr_data_get ((GPrivateNSPR *) private)->data = value;
+}
+
+static gpointer
+g_private_get_nspr_impl (GPrivate * private)
+{
+ if (!private)
+ return NULL;
+
+ return g_private_nspr_data_get ((GPrivateNSPR *) private)->data;
+}
+
+static GThreadFunctions g_thread_functions_for_glib_use_default =
+{
+ (GMutex * (*)())PR_NewLock,
+ (void (*)(GMutex *)) PR_Lock,
+ g_mutex_trylock_nspr_impl,
+ (void (*)(GMutex *)) PR_Unlock,
+ (void (*)(GMutex *)) PR_DestroyLock,
+ (GCond * (*)())PRP_NewNakedCondVar,
+ (void (*)(GCond *)) PRP_NakedNotify,
+ (void (*)(GCond *)) PRP_NakedBroadcast,
+ g_cond_wait_nspr_impl,
+ g_cond_timed_wait_nspr_impl,
+ (void (*)(GCond *)) PRP_DestroyNakedCondVar,
+ g_private_new_nspr_impl,
+ g_private_get_nspr_impl,
+ g_private_set_nspr_impl
+};