1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * gthread.c: nspr thread system implementation
5 * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 * Modified by the GLib Team and others 1997-1999. See the AUTHORS
25 * file for a list of people on the GLib Team. See the ChangeLog
26 * files for a list of changes. These files are distributed with
27 * GLib at ftp://ftp.gtk.org/pub/gtk/.
38 #ifdef G_DISABLE_ASSERT
40 #define STDERR_ASSERT(expr)
42 #else /* G_DISABLE_ASSERT */
44 #define STDERR_ASSERT(expr) G_STMT_START{ \
46 g_log (G_LOG_DOMAIN, \
48 "file %s: line %d: assertion failed: (%s)", \
53 #endif /* G_DISABLE_ASSERT */
55 /* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
56 functions from gmem.c and gmessages.c; */
59 g_mutex_trylock_nspr_impl (GMutex
* mutex
)
61 PRStatus status
= PRP_TryLock ((PRLock
*) mutex
);
62 if (status
== PR_SUCCESS
)
70 g_cond_wait_nspr_impl (GCond
* cond
,
71 GMutex
* entered_mutex
)
73 PRStatus status
= PRP_NakedWait ((PRCondVar
*) cond
,
74 (PRLock
*) entered_mutex
,
75 PR_INTERVAL_NO_TIMEOUT
);
76 g_assert (status
== PR_SUCCESS
);
79 #define G_MICROSEC 1000000
82 g_cond_timed_wait_nspr_impl (GCond
* cond
,
83 GMutex
* entered_mutex
,
87 PRIntervalTime interval
;
88 GTimeVal current_time
;
91 g_return_val_if_fail (cond
!= NULL
, FALSE
);
92 g_return_val_if_fail (entered_mutex
!= NULL
, FALSE
);
94 g_get_current_time (¤t_time
);
96 if (abs_time
->tv_sec
< current_time
.tv_sec
||
97 (abs_time
->tv_sec
== current_time
.tv_sec
&&
98 abs_time
->tv_usec
< current_time
.tv_usec
))
101 interval
= PR_SecondsToInterval (abs_time
->tv_sec
- current_time
.tv_sec
);
102 microsecs
= abs_time
->tv_usec
- current_time
.tv_usec
;
104 interval
-= PR_MicrosecondsToInterval (-microsecs
);
106 interval
+= PR_MicrosecondsToInterval (microsecs
);
108 status
= PRP_NakedWait ((PRCondVar
*) cond
, (PRLock
*) entered_mutex
,
111 g_assert (status
== PR_SUCCESS
);
113 g_get_current_time (¤t_time
);
115 if (abs_time
->tv_sec
< current_time
.tv_sec
||
116 (abs_time
->tv_sec
== current_time
.tv_sec
&&
117 abs_time
->tv_usec
< current_time
.tv_usec
))
122 typedef struct _GPrivateNSPRData GPrivateNSPRData
;
123 struct _GPrivateNSPRData
126 GDestroyNotify destructor
;
129 typedef struct _GPrivateNSPR GPrivateNSPR
;
133 GDestroyNotify destructor
;
136 static GPrivateNSPRData
*
137 g_private_nspr_data_constructor (GDestroyNotify destructor
, gpointer data
)
139 /* we can not use g_new and friends, as they might use private data by
141 GPrivateNSPRData
*private_key
= malloc (sizeof (GPrivateNSPRData
));
142 g_assert (private_key
);
143 private_key
->data
= data
;
144 private_key
->destructor
= destructor
;
150 g_private_nspr_data_destructor (gpointer data
)
152 GPrivateNSPRData
*private_key
= data
;
153 if (private_key
->destructor
&& private_key
->data
)
154 (*private_key
->destructor
) (private_key
->data
);
159 g_private_new_nspr_impl (GDestroyNotify destructor
)
161 GPrivateNSPR
*result
= g_new (GPrivateNSPR
, 1);
162 PRStatus status
= PR_NewThreadPrivateIndex (&result
->private_key
,
163 g_private_nspr_data_destructor
);
164 g_assert (status
== PR_SUCCESS
);
166 result
->destructor
= destructor
;
167 return (GPrivate
*) result
;
170 /* NOTE: the functions g_private_get and g_private_set may not use
171 functions from gmem.c and gmessages.c */
173 static GPrivateNSPRData
*
174 g_private_nspr_data_get (GPrivateNSPR
* private_key
)
176 GPrivateNSPRData
*data
;
178 STDERR_ASSERT (private_key
);
180 data
= PR_GetThreadPrivate (private_key
->private_key
);
183 data
= g_private_nspr_data_constructor (private_key
->destructor
, NULL
);
184 STDERR_ASSERT (PR_SetThreadPrivate (private_key
->private_key
, data
)
192 g_private_set_nspr_impl (GPrivate
* private_key
, gpointer value
)
197 g_private_nspr_data_get ((GPrivateNSPR
*) private_key
)->data
= value
;
201 g_private_get_nspr_impl (GPrivate
* private_key
)
206 return g_private_nspr_data_get ((GPrivateNSPR
*) private_key
)->data
;
209 static GThreadFunctions g_thread_functions_for_glib_use_default
=
211 (GMutex
* (*)())PR_NewLock
,
212 (void (*)(GMutex
*)) PR_Lock
,
213 g_mutex_trylock_nspr_impl
,
214 (void (*)(GMutex
*)) PR_Unlock
,
215 (void (*)(GMutex
*)) PR_DestroyLock
,
216 (GCond
* (*)())PRP_NewNakedCondVar
,
217 (void (*)(GCond
*)) PRP_NakedNotify
,
218 (void (*)(GCond
*)) PRP_NakedBroadcast
,
219 g_cond_wait_nspr_impl
,
220 g_cond_timed_wait_nspr_impl
,
221 (void (*)(GCond
*)) PRP_DestroyNakedCondVar
,
222 g_private_new_nspr_impl
,
223 g_private_get_nspr_impl
,
224 g_private_set_nspr_impl