+#else /* G_THREADS_IMPL_DCE */
+ {
+ void* data;
+ posix_check_cmd (pthread_getspecific (*(pthread_key_t *) private_key,
+ &data));
+ return data;
+ }
+#endif
+}
+
+static void
+g_thread_create_posix_impl (GThreadFunc thread_func,
+ gpointer arg,
+ gulong stack_size,
+ gboolean joinable,
+ gboolean bound,
+ GThreadPriority priority,
+ gpointer thread,
+ GError **error)
+{
+ pthread_attr_t attr;
+ gint ret;
+
+ g_return_if_fail (thread_func);
+ g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
+ g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
+
+ posix_check_cmd (pthread_attr_init (&attr));
+
+#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
+ if (stack_size)
+ {
+ stack_size = MAX (g_thread_min_stack_size, stack_size);
+ /* No error check here, because some systems can't do it and
+ * we simply don't want threads to fail because of that. */
+ pthread_attr_setstacksize (&attr, stack_size);
+ }
+#endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */
+
+#ifdef PTHREAD_SCOPE_SYSTEM
+ if (bound)
+ /* No error check here, because some systems can't do it and we
+ * simply don't want threads to fail because of that. */
+ pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
+#endif /* PTHREAD_SCOPE_SYSTEM */
+
+#ifdef G_THREADS_IMPL_POSIX
+ posix_check_cmd (pthread_attr_setdetachstate (&attr,
+ joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED));
+#endif /* G_THREADS_IMPL_POSIX */
+
+#ifdef HAVE_PRIORITIES
+# ifdef G_THREADS_IMPL_POSIX
+ {
+ struct sched_param sched;
+ posix_check_cmd (pthread_attr_getschedparam (&attr, &sched));
+ sched.sched_priority = g_thread_priority_map [priority];
+ posix_check_cmd_prio (pthread_attr_setschedparam (&attr, &sched));
+ }
+# else /* G_THREADS_IMPL_DCE */
+ posix_check_cmd_prio
+ (pthread_attr_setprio (&attr, g_thread_priority_map [priority]));
+# endif /* G_THREADS_IMPL_DCE */
+#endif /* HAVE_PRIORITIES */
+ ret = posix_error (pthread_create (thread, &attr,
+ (void* (*)(void*))thread_func, arg));
+
+ posix_check_cmd (pthread_attr_destroy (&attr));
+
+ if (ret == EAGAIN)
+ {
+ g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN,
+ "Error creating thread: %s", g_strerror (ret));
+ return;
+ }
+
+ posix_check_err (ret, "pthread_create");
+
+#ifdef G_THREADS_IMPL_DCE
+ if (!joinable)
+ posix_check_cmd (pthread_detach (thread));
+#endif /* G_THREADS_IMPL_DCE */
+}
+
+static void
+g_thread_yield_posix_impl (void)
+{
+ POSIX_YIELD_FUNC;
+}
+
+static void
+g_thread_join_posix_impl (gpointer thread)
+{
+ gpointer ignore;
+ posix_check_cmd (pthread_join (*(pthread_t*)thread, &ignore));
+}
+
+static void
+g_thread_exit_posix_impl (void)
+{
+ pthread_exit (NULL);
+}
+
+static void
+g_thread_set_priority_posix_impl (gpointer thread, GThreadPriority priority)
+{
+ g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
+ g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
+#ifdef HAVE_PRIORITIES
+# ifdef G_THREADS_IMPL_POSIX
+ {
+ struct sched_param sched;
+ int policy;
+ posix_check_cmd (pthread_getschedparam (*(pthread_t*)thread, &policy,
+ &sched));
+ sched.sched_priority = g_thread_priority_map [priority];
+ posix_check_cmd_prio (pthread_setschedparam (*(pthread_t*)thread, policy,
+ &sched));
+ }
+# else /* G_THREADS_IMPL_DCE */
+ posix_check_cmd_prio (pthread_setprio (*(pthread_t*)thread,
+ g_thread_priority_map [priority]));
+# endif
+#endif /* HAVE_PRIORITIES */
+}
+
+static void
+g_thread_self_posix_impl (gpointer thread)
+{
+ *(pthread_t*)thread = pthread_self();
+}
+
+static gboolean
+g_thread_equal_posix_impl (gpointer thread1, gpointer thread2)
+{
+ return (pthread_equal (*(pthread_t*)thread1, *(pthread_t*)thread2) != 0);