⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gthread.c

📁 嵌入式下基于MiniGUI的Web Browser
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GLIB - Library of useful routines for C programming * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald * * gmutex.c: MT safety related functions * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe *                Owen Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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. *//* * Modified by the GLib Team and others 1997-2000.  See the AUTHORS * file for a list of people on the GLib Team.  See the ChangeLog * files for a list of changes.  These files are distributed with * GLib at ftp://ftp.gtk.org/pub/gtk/.  *//*  * MT safe */#include "glibconfig.h"#include "glib.h"#ifdef G_THREAD_USE_PID_SURROGATE#include <sys/types.h>#include <sys/time.h>#include <sys/resource.h>#include <errno.h>#endif /* G_THREAD_USE_PID_SURROGATE */#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <string.h>#if GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P# define g_system_thread_equal_simple(thread1, thread2)			\   ((thread1).dummy_pointer == (thread2).dummy_pointer)# define g_system_thread_assign(dest, src)				\   ((dest).dummy_pointer = (src).dummy_pointer)#else /* GLIB_SIZEOF_SYSTEM_THREAD != SIZEOF_VOID_P */# define g_system_thread_equal_simple(thread1, thread2)			\   (memcmp (&(thread1), &(thread2), GLIB_SIZEOF_SYSTEM_THREAD) == 0)# define g_system_thread_assign(dest, src)				\   (memcpy (&(dest), &(src), GLIB_SIZEOF_SYSTEM_THREAD))#endif /* GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P */#define g_system_thread_equal(thread1, thread2)				\  (g_thread_functions_for_glib_use.thread_equal ? 			\   g_thread_functions_for_glib_use.thread_equal (&(thread1), &(thread2)) :\   g_system_thread_equal_simple((thread1), (thread2)))GQuark g_thread_error_quark (void){  static GQuark quark;  if (!quark)    quark = g_quark_from_static_string ("g_thread_error");  return quark;}/* Keep this in sync with GRealThread in gmain.c! */typedef struct _GRealThread GRealThread;struct  _GRealThread{  GThread thread;  gpointer private_data;  gpointer retval;  GSystemThread system_thread;#ifdef G_THREAD_USE_PID_SURROGATE  pid_t pid;#endif /* G_THREAD_USE_PID_SURROGATE */};#ifdef G_THREAD_USE_PID_SURROGATEstatic gint priority_map[] = { 15, 0, -15, -20 };static gboolean prio_warned = FALSE;# define SET_PRIO(pid, prio) G_STMT_START{				\  gint error = setpriority (PRIO_PROCESS, (pid), priority_map[prio]);	\  if (error == -1 && errno == EACCES && !prio_warned)			\    {									\      prio_warned = TRUE;						\      g_warning ("Priorities can only be increased by root.");		\    }									\  }G_STMT_END#endif /* G_THREAD_USE_PID_SURROGATE */typedef struct _GStaticPrivateNode GStaticPrivateNode;struct _GStaticPrivateNode{  gpointer       data;  GDestroyNotify destroy;};static void g_thread_cleanup (gpointer data);static void g_thread_fail (void);/* Global variables */static GSystemThread zero_thread; /* This is initialized to all zero */gboolean g_thread_use_default_impl = TRUE;gboolean g_threads_got_initialized = FALSE;#if defined(G_PLATFORM_WIN32) && defined(__GNUC__)__declspec(dllexport)#endifGThreadFunctions g_thread_functions_for_glib_use = {  (GMutex*(*)())g_thread_fail,                 /* mutex_new */  NULL,                                        /* mutex_lock */  NULL,                                        /* mutex_trylock */  NULL,                                        /* mutex_unlock */  NULL,                                        /* mutex_free */  (GCond*(*)())g_thread_fail,                  /* cond_new */  NULL,                                        /* cond_signal */  NULL,                                        /* cond_broadcast */  NULL,                                        /* cond_wait */  NULL,                                        /* cond_timed_wait  */  NULL,                                        /* cond_free */  (GPrivate*(*)(GDestroyNotify))g_thread_fail, /* private_new */  NULL,                                        /* private_get */  NULL,                                        /* private_set */  (void(*)(GThreadFunc, gpointer, gulong, 	   gboolean, gboolean, GThreadPriority, 	   gpointer, GError**))g_thread_fail,  /* thread_create */  NULL,                                        /* thread_yield */  NULL,                                        /* thread_join */  NULL,                                        /* thread_exit */  NULL,                                        /* thread_set_priority */  NULL                                         /* thread_self */}; /* Local data */static GMutex   *g_mutex_protect_static_mutex_allocation = NULL;static GPrivate *g_thread_specific_private = NULL;static GSList   *g_thread_all_threads = NULL;static GSList   *g_thread_free_indeces = NULL;G_LOCK_DEFINE_STATIC (g_thread);/* This must be called only once, before any threads are created. * It will only be called from g_thread_init() in -lgthread. */voidg_mutex_init (void){  GRealThread* main_thread;   /* We let the main thread (the one that calls g_thread_init) inherit   * the data, that it set before calling g_thread_init   */  main_thread = (GRealThread*) g_thread_self ();  g_thread_specific_private = g_private_new (g_thread_cleanup);  G_THREAD_UF (private_set, (g_thread_specific_private, main_thread));  G_THREAD_UF (thread_self, (&main_thread->system_thread));  g_mutex_protect_static_mutex_allocation = g_mutex_new ();}void g_static_mutex_init (GStaticMutex *mutex){  static GStaticMutex init_mutex = G_STATIC_MUTEX_INIT;  g_return_if_fail (mutex);  *mutex = init_mutex;}GMutex *g_static_mutex_get_mutex_impl (GMutex** mutex){  if (!g_thread_supported ())    return NULL;  g_assert (g_mutex_protect_static_mutex_allocation);  g_mutex_lock (g_mutex_protect_static_mutex_allocation);  if (!(*mutex))     *mutex = g_mutex_new ();   g_mutex_unlock (g_mutex_protect_static_mutex_allocation);    return *mutex;}voidg_static_mutex_free (GStaticMutex* mutex){  GMutex **runtime_mutex;    g_return_if_fail (mutex);  /* The runtime_mutex is the first (or only) member of GStaticMutex,   * see both versions (of glibconfig.h) in configure.in */  runtime_mutex = ((GMutex**)mutex);    if (*runtime_mutex)    g_mutex_free (*runtime_mutex);  *runtime_mutex = NULL;}void     g_static_rec_mutex_init (GStaticRecMutex *mutex){  static GStaticRecMutex init_mutex = G_STATIC_REC_MUTEX_INIT;    g_return_if_fail (mutex);  *mutex = init_mutex;}voidg_static_rec_mutex_lock (GStaticRecMutex* mutex){  GSystemThread self;  g_return_if_fail (mutex);  if (!g_thread_supported ())    return;  G_THREAD_UF (thread_self, (&self));  if (g_system_thread_equal (self, mutex->owner))    {      mutex->depth++;      return;    }  g_static_mutex_lock (&mutex->mutex);  g_system_thread_assign (mutex->owner, self);  mutex->depth = 1;}gbooleang_static_rec_mutex_trylock (GStaticRecMutex* mutex){  GSystemThread self;  g_return_val_if_fail (mutex, FALSE);  if (!g_thread_supported ())    return TRUE;  G_THREAD_UF (thread_self, (&self));  if (g_system_thread_equal (self, mutex->owner))    {      mutex->depth++;      return TRUE;    }  if (!g_static_mutex_trylock (&mutex->mutex))    return FALSE;  g_system_thread_assign (mutex->owner, self);  mutex->depth = 1;  return TRUE;}voidg_static_rec_mutex_unlock (GStaticRecMutex* mutex){  g_return_if_fail (mutex);  if (!g_thread_supported ())    return;  if (mutex->depth > 1)    {      mutex->depth--;      return;    }  g_system_thread_assign (mutex->owner, zero_thread);  g_static_mutex_unlock (&mutex->mutex);  }voidg_static_rec_mutex_lock_full   (GStaticRecMutex *mutex,				guint            depth){  GSystemThread self;  g_return_if_fail (mutex);  if (!g_thread_supported ())    return;  G_THREAD_UF (thread_self, (&self));  if (g_system_thread_equal (self, mutex->owner))    {      mutex->depth += depth;      return;    }  g_static_mutex_lock (&mutex->mutex);  g_system_thread_assign (mutex->owner, self);  mutex->depth = depth;}guint    g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex){  guint depth;  g_return_val_if_fail (mutex, 0);  if (!g_thread_supported ())    return 1;  depth = mutex->depth;  g_system_thread_assign (mutex->owner, zero_thread);  mutex->depth = 0;  g_static_mutex_unlock (&mutex->mutex);  return depth;}voidg_static_rec_mutex_free (GStaticRecMutex *mutex){  g_return_if_fail (mutex);  g_static_mutex_free (&mutex->mutex);}void     g_static_private_init (GStaticPrivate *private_key){  private_key->index = 0;}gpointerg_static_private_get (GStaticPrivate *private_key){  GRealThread *self = (GRealThread*) g_thread_self ();  GArray *array;  array = self->private_data;  if (!array)    return NULL;  if (!private_key->index)    return NULL;  else if (private_key->index <= array->len)    return g_array_index (array, GStaticPrivateNode, 			  private_key->index - 1).data;  else    return NULL;}voidg_static_private_set (GStaticPrivate *private_key, 		      gpointer        data,		      GDestroyNotify  notify){  GRealThread *self = (GRealThread*) g_thread_self ();  GArray *array;  static guint next_index = 0;  GStaticPrivateNode *node;  array = self->private_data;  if (!array)    {      array = g_array_new (FALSE, TRUE, sizeof (GStaticPrivateNode));      self->private_data = array;    }  if (!private_key->index)    {      G_LOCK (g_thread);      if (!private_key->index)	{	  if (g_thread_free_indeces)	    {	      private_key->index = 		GPOINTER_TO_UINT (g_thread_free_indeces->data);	      g_thread_free_indeces = 		g_slist_delete_link (g_thread_free_indeces,				     g_thread_free_indeces);	    }	  else	    private_key->index = ++next_index;	}      G_UNLOCK (g_thread);    }  if (private_key->index > array->len)    g_array_set_size (array, private_key->index);  node = &g_array_index (array, GStaticPrivateNode, private_key->index - 1);  if (node->destroy)    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -