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

📄 gmain.c

📁 嵌入式下基于MiniGUI的Web Browser
💻 C
📖 第 1 页 / 共 5 页
字号:
  g_static_mutex_free (&context->mutex);#endif  g_ptr_array_free (context->pending_dispatches, TRUE);  g_free (context->cached_poll_array);    g_mem_chunk_destroy (context->poll_chunk);#ifdef G_THREADS_ENABLED  if (g_thread_supported())    {#ifndef G_OS_WIN32      close (context->wake_up_pipe[0]);      close (context->wake_up_pipe[1]);#else      CloseHandle (context->wake_up_semaphore);#endif    }  else    main_contexts_without_pipe = g_slist_remove (main_contexts_without_pipe, 						 context);#endif    g_free (context);}/** * g_main_context_unref: * @context: a #GMainContext *  * Decreases the reference count on a #GMainContext object by one. If * the result is zero, free the context and free all associated memory. **/voidg_main_context_unref (GMainContext *context){  g_return_if_fail (context != NULL);  g_return_if_fail (context->ref_count > 0);   LOCK_CONTEXT (context);  g_main_context_unref_and_unlock (context);}#ifdef G_THREADS_ENABLEDstatic void g_main_context_init_pipe (GMainContext *context){# ifndef G_OS_WIN32  if (pipe (context->wake_up_pipe) < 0)    g_error ("Cannot create pipe main loop wake-up: %s\n",	     g_strerror (errno));    context->wake_up_rec.fd = context->wake_up_pipe[0];  context->wake_up_rec.events = G_IO_IN;# else  context->wake_up_semaphore = CreateSemaphore (NULL, 0, 100, NULL);  if (context->wake_up_semaphore == NULL)    g_error ("Cannot create wake-up semaphore: %s",	     g_win32_error_message (GetLastError ()));  context->wake_up_rec.fd = (gint) context->wake_up_semaphore;  context->wake_up_rec.events = G_IO_IN;#  ifdef G_MAIN_POLL_DEBUG  g_print ("wake-up semaphore: %#x\n", (guint) context->wake_up_semaphore);#  endif# endif  g_main_context_add_poll_unlocked (context, 0, &context->wake_up_rec);}voidg_main_thread_init (){  GSList *curr = main_contexts_without_pipe;  while (curr)    {      g_main_context_init_pipe ((GMainContext *)curr->data);      curr = curr->next;    }  g_slist_free (main_contexts_without_pipe);  main_contexts_without_pipe = NULL;  }#endif /* G_THREADS_ENABLED *//** * g_main_context_new: *  * Creates a new #GMainContext strcuture *  * Return value: the new #GMainContext **/GMainContext *g_main_context_new (){  GMainContext *context = g_new0 (GMainContext, 1);#ifdef G_THREADS_ENABLED  g_static_mutex_init (&context->mutex);  context->owner = NULL;  context->waiters = NULL;#endif        context->ref_count = 1;      context->next_id = 1;            context->source_list = NULL;#if HAVE_POLL      context->poll_func = (GPollFunc)poll;#else      context->poll_func = g_poll;#endif      context->cached_poll_array = NULL;      context->cached_poll_array_size = 0;            context->pending_dispatches = g_ptr_array_new ();            context->time_is_current = FALSE;#ifdef G_THREADS_ENABLED      if (g_thread_supported ())    g_main_context_init_pipe (context);  else    main_contexts_without_pipe = g_slist_prepend (main_contexts_without_pipe, 						  context);#endif  return context;}/** * g_main_context_default: *  * Returns the default main context. This is the main context used * for main loop functions when a main loop is not explicitly * specified. *  * Return value: the default main context. **/GMainContext *g_main_context_default (void){  /* Slow, but safe */    G_LOCK (main_loop);  if (!default_main_context)    default_main_context = g_main_context_new ();  G_UNLOCK (main_loop);  return default_main_context;}/* Hooks for adding to the main loop *//** * g_source_new: * @source_funcs: structure containing functions that implement *                the sources behavior. * @struct_size: size of the #GSource structure to create. *  * Creates a new #GSource structure. The size is specified to * allow creating structures derived from #GSource that contain * additional data. The size passed in must be at least * <literal>sizeof (GSource)</literal>. *  * The source will not initially be associated with any #GMainContext * and must be added to one with g_source_add() before it will be * executed. *  * Return value: the newly-created #GSource. **/GSource *g_source_new (GSourceFuncs *source_funcs,	      guint         struct_size){  GSource *source;  g_return_val_if_fail (source_funcs != NULL, NULL);  g_return_val_if_fail (struct_size >= sizeof (GSource), NULL);    source = (GSource*) g_malloc0 (struct_size);  source->source_funcs = source_funcs;  source->ref_count = 1;    source->priority = G_PRIORITY_DEFAULT;  source->flags = G_HOOK_FLAG_ACTIVE;  /* NULL/0 initialization for all other fields */    return source;}/* Holds context's lock */static voidg_source_list_add (GSource      *source,		   GMainContext *context){  GSource *tmp_source, *last_source;    last_source = NULL;  tmp_source = context->source_list;  while (tmp_source && tmp_source->priority <= source->priority)    {      last_source = tmp_source;      tmp_source = tmp_source->next;    }  source->next = tmp_source;  if (tmp_source)    tmp_source->prev = source;    source->prev = last_source;  if (last_source)    last_source->next = source;  else    context->source_list = source;}/* Holds context's lock */static voidg_source_list_remove (GSource      *source,		      GMainContext *context){  if (source->prev)    source->prev->next = source->next;  else    context->source_list = source->next;  if (source->next)    source->next->prev = source->prev;  source->prev = NULL;  source->next = NULL;}/** * g_source_attach: * @source: a #GSource * @context: a #GMainContext (if %NULL, the default context will be used) *  * Adds a #GSource to a @context so that it will be executed within * that context. * * Return value: the ID for the source within the #GMainContext **/guintg_source_attach (GSource      *source,		 GMainContext *context){  guint result = 0;  GSList *tmp_list;  g_return_val_if_fail (source->context == NULL, 0);  g_return_val_if_fail (!SOURCE_DESTROYED (source), 0);    if (!context)    context = g_main_context_default ();  LOCK_CONTEXT (context);  source->context = context;  result = source->source_id = context->next_id++;  source->ref_count++;  g_source_list_add (source, context);  tmp_list = source->poll_fds;  while (tmp_list)    {      g_main_context_add_poll_unlocked (context, source->priority, tmp_list->data);      tmp_list = tmp_list->next;    }#ifdef G_THREADS_ENABLED  /* Now wake up the main loop if it is waiting in the poll() */  g_main_context_wakeup_unlocked (context);#endif  UNLOCK_CONTEXT (context);  return result;}static voidg_source_destroy_internal (GSource      *source,			   GMainContext *context,			   gboolean      have_lock){  if (!have_lock)    LOCK_CONTEXT (context);    if (!SOURCE_DESTROYED (source))    {      GSList *tmp_list;      gpointer old_cb_data;      GSourceCallbackFuncs *old_cb_funcs;            source->flags &= ~G_HOOK_FLAG_ACTIVE;      old_cb_data = source->callback_data;      old_cb_funcs = source->callback_funcs;      source->callback_data = NULL;      source->callback_funcs = NULL;      if (old_cb_funcs)	{	  UNLOCK_CONTEXT (context);	  old_cb_funcs->unref (old_cb_data);	  LOCK_CONTEXT (context);	}            tmp_list = source->poll_fds;      while (tmp_list)	{	  g_main_context_remove_poll_unlocked (context, tmp_list->data);	  tmp_list = tmp_list->next;	}            g_source_unref_internal (source, context, TRUE);    }  if (!have_lock)    UNLOCK_CONTEXT (context);}/** * g_source_destroy: * @source: a #GSource *  * Removes a source from its #GMainContext, if any, and mark it as * destroyed.  The source cannot be subsequently added to another * context. **/voidg_source_destroy (GSource *source){  GMainContext *context;    g_return_if_fail (source != NULL);    context = source->context;    if (context)    g_source_destroy_internal (source, context, FALSE);  else    source->flags &= ~G_HOOK_FLAG_ACTIVE;}/** * g_source_get_id: * @source: a #GSource *  * Returns the numeric ID for a particular source. The ID of a source * is unique within a particular main loop context. The reverse * mapping from ID to source is done by g_main_context_find_source_by_id(). * * Return value: the ID for the source **/guintg_source_get_id (GSource *source){  guint result;    g_return_val_if_fail (source != NULL, 0);  g_return_val_if_fail (source->context != NULL, 0);  LOCK_CONTEXT (source->context);  result = source->source_id;  UNLOCK_CONTEXT (source->context);    return result;}/** * g_source_get_context: * @source: a #GSource *  * Gets the #GMainContext with which the source is associated. * Calling this function on a destroyed source is an error. *  * Return value: the #GMainContext with which the source is associated, *               or %NULL if the context has not yet been added *               to a source. **/GMainContext *g_source_get_context (GSource *source){  g_return_val_if_fail (!SOURCE_DESTROYED (source), NULL);  return source->context;}/** * g_source_add_poll: * @source:a #GSource  * @fd: a #GPollFD structure holding information about a file *      descriptor to watch. *  * Adds a file descriptor to the set of file descriptors polled for * this source. This is usually combined with g_source_new() to add an * event source. The event source's check function will typically test * the @revents field in the #GPollFD struct and return %TRUE if events need * to be processed. **/voidg_source_add_poll (GSource *source,		   GPollFD *fd){  GMainContext *context;    g_return_if_fail (source != NULL);  g_return_if_fail (fd != NULL);  g_return_if_fail (!SOURCE_DESTROYED (source));    context = source->context;  if (context)    LOCK_CONTEXT (context);    source->poll_fds = g_slist_prepend (source->poll_fds, fd);  if (context)    {      g_main_context_add_poll_unlocked (context, source->priority, fd);      UNLOCK_CONTEXT (context);    }}/** * g_source_remove_poll: * @source:a #GSource  * @fd: a #GPollFD structure previously passed to g_source_poll(). *  * Removes a file descriptor from the set of file descriptors polled for * this source.  **/voidg_source_remove_poll (GSource *source,		      GPollFD *fd){  GMainContext *context;    g_return_if_fail (source != NULL);  g_return_if_fail (fd != NULL);  g_return_if_fail (!SOURCE_DESTROYED (source));    context = source->context;  if (context)    LOCK_CONTEXT (context);    source->poll_fds = g_slist_remove (source->poll_fds, fd);  if (context)    {      g_main_context_remove_poll_unlocked (context, fd);      UNLOCK_CONTEXT (context);    }}/** * g_source_set_callback_indirect: * @source: the source * @callback_data: pointer to callback data "object" * @callback_funcs: functions for reference counting @callback_data *                  and getting the callback and data *  * Sets the callback function storing the data as a refcounted callback * "object". This is used to implement g_source_set_callback_closure() * and internally. Note that calling g_source_set_callback_indirect() assumes * an initial reference count on @callback_data, and thus * @callback_funcs->unref will eventually be called once more * than @callback_funcs->ref. **/voidg_source_set_callback_indirect (GSource              *source,				gpointer              callback_data,				GSourceCallbackFuncs *callback_funcs){  GMainContext *context;  gpointer old_cb_data;  GSourceCallbackFuncs *old_cb_funcs;    g_return_if_fail (source != NULL);  g_return_if_fail (callback_funcs != NULL || callback_data == NULL);  context = source->context;  if (context)    LOCK_CONTEXT (context);  old_cb_data = source->callback_data;  old_cb_funcs = source->callback_funcs;  source->callback_data = callback_data;  source->callback_funcs = callback_funcs;    if (context)    UNLOCK_CONTEXT (context);    if (old_cb_funcs)    old_cb_funcs->unref (old_cb_data);}static voidg_source_callback_ref (gpointer cb_data){  GSourceCallback *callback = cb_data;  callback->ref_count++;}static voidg_source_callback_unref (gpointer cb_data){  GSourceCallback *callback = cb_data;  callback->ref_count--;  if (callback->ref_count == 0)    {      if (callback->notify)	callback->notify (callback->data);      g_free (callback);    }}static voidg_source_callback_get (gpointer     cb_data,		       GSource     *source, 		       GSourceFunc *func,		       gpointer    *data){  GSourceCallback *callback = cb_data;  *func = callback->func;  *data = callback->data;}static GSourceCallbackFuncs g_source_callback_funcs = {  g_source_callback_ref,  g_source_callback_unref,  g_source_callback_get,};/** * g_source_set_callback: * @source: the source * @func: a callback function * @data: the data to pass to callback function

⌨️ 快捷键说明

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