📄 gmain.c
字号:
* @notify: a function to call when @data is no longer in use, or %NULL. * * Sets the callback function for a source. **/voidg_source_set_callback (GSource *source, GSourceFunc func, gpointer data, GDestroyNotify notify){ GSourceCallback *new_callback; g_return_if_fail (source != NULL); new_callback = g_new (GSourceCallback, 1); new_callback->ref_count = 1; new_callback->func = func; new_callback->data = data; new_callback->notify = notify; g_source_set_callback_indirect (source, new_callback, &g_source_callback_funcs);}/** * g_source_set_priority: * @source: a #GSource * @priority: the new priority. * * Sets the priority of a source. While the main loop is being * run, a source will be dispatched if it is ready to be dispatched and no sources * at a higher (numerically smaller) priority are ready to be dispatched. **/voidg_source_set_priority (GSource *source, gint priority){ GSList *tmp_list; GMainContext *context; g_return_if_fail (source != NULL); context = source->context; if (context) LOCK_CONTEXT (context); source->priority = priority; if (context) { source->next = NULL; source->prev = NULL; tmp_list = source->poll_fds; while (tmp_list) { g_main_context_remove_poll_unlocked (context, tmp_list->data); g_main_context_add_poll_unlocked (context, priority, tmp_list->data); tmp_list = tmp_list->next; } UNLOCK_CONTEXT (source->context); }}/** * g_source_get_priority: * @source: a #GSource * * Gets the priority of a source. * * Return value: the priority of the source **/gintg_source_get_priority (GSource *source){ g_return_val_if_fail (source != NULL, 0); return source->priority;}/** * g_source_set_can_recurse: * @source: a #GSource * @can_recurse: whether recursion is allowed for this source * * Sets whether a source can be called recursively. If @can_recurse is * %TRUE, then while the source is being dispatched then this source * will be processed normally. Otherwise, all processing of this * source is blocked until the dispatch function returns. **/voidg_source_set_can_recurse (GSource *source, gboolean can_recurse){ GMainContext *context; g_return_if_fail (source != NULL); context = source->context; if (context) LOCK_CONTEXT (context); if (can_recurse) source->flags |= G_SOURCE_CAN_RECURSE; else source->flags &= ~G_SOURCE_CAN_RECURSE; if (context) UNLOCK_CONTEXT (context);}/** * g_source_get_can_recurse: * @source: a #GSource * * Checks whether a source is allowed to be called recursively. * see g_source_set_can_recurse(). * * Return value: whether recursion is allowed. **/gbooleang_source_get_can_recurse (GSource *source){ g_return_val_if_fail (source != NULL, FALSE); return (source->flags & G_SOURCE_CAN_RECURSE) != 0;}/** * g_source_ref: * @source: a #GSource * * Increases the reference count on a source by one. * * Return value: @source **/GSource *g_source_ref (GSource *source){ GMainContext *context; g_return_val_if_fail (source != NULL, NULL); context = source->context; if (context) LOCK_CONTEXT (context); source->ref_count++; if (context) UNLOCK_CONTEXT (context); return source;}/* g_source_unref() but possible to call within context lock */static voidg_source_unref_internal (GSource *source, GMainContext *context, gboolean have_lock){ gpointer old_cb_data = NULL; GSourceCallbackFuncs *old_cb_funcs = NULL; g_return_if_fail (source != NULL); if (!have_lock && context) LOCK_CONTEXT (context); source->ref_count--; if (source->ref_count == 0) { old_cb_data = source->callback_data; old_cb_funcs = source->callback_funcs; source->callback_data = NULL; source->callback_funcs = NULL; if (context && !SOURCE_DESTROYED (source)) { g_warning (G_STRLOC ": ref_count == 0, but source is still attached to a context!"); source->ref_count++; } else if (context) g_source_list_remove (source, context); if (source->source_funcs->finalize) source->source_funcs->finalize (source); g_slist_free (source->poll_fds); source->poll_fds = NULL; g_free (source); } if (!have_lock && context) UNLOCK_CONTEXT (context); if (old_cb_funcs) { if (have_lock) UNLOCK_CONTEXT (context); old_cb_funcs->unref (old_cb_data); if (have_lock) LOCK_CONTEXT (context); }}/** * g_source_unref: * @source: a #GSource * * Decreases the reference count of a source by one. If the * resulting reference count is zero the source and associated * memory will be destroyed. **/voidg_source_unref (GSource *source){ g_return_if_fail (source != NULL); g_source_unref_internal (source, source->context, FALSE);}/** * g_main_context_find_source_by_id: * @context: a #GMainContext (if %NULL, the default context will be used) * @source_id: the source ID, as returned by g_source_get_id() * * Finds a #GSource given a pair of context and ID * * Return value: the #GSource if found, otherwise, %NULL **/GSource *g_main_context_find_source_by_id (GMainContext *context, guint source_id){ GSource *source; g_return_val_if_fail (source_id > 0, FALSE); if (context == NULL) context = g_main_context_default (); LOCK_CONTEXT (context); source = context->source_list; while (source) { if (!SOURCE_DESTROYED (source) && source->source_id == source_id) break; source = source->next; } UNLOCK_CONTEXT (context); return source;}/** * g_main_context_find_source_by_funcs_user_data: * @context: a #GMainContext (if %NULL, the default context will be used). * @funcs: the @source_funcs passed to g_source_new(). * @user_data: the user data from the callback. * * Finds a source with the given source functions and user data. If * multiple sources exist with the same source function and user data, * the first one found will be returned. * * Return value: the source, if one was found, otherwise %NULL **/GSource *g_main_context_find_source_by_funcs_user_data (GMainContext *context, GSourceFuncs *funcs, gpointer user_data){ GSource *source; g_return_val_if_fail (funcs != NULL, FALSE); if (context == NULL) context = g_main_context_default (); LOCK_CONTEXT (context); source = context->source_list; while (source) { if (!SOURCE_DESTROYED (source) && source->source_funcs == funcs && source->callback_funcs) { GSourceFunc callback; gpointer callback_data; source->callback_funcs->get (source->callback_data, source, &callback, &callback_data); if (callback_data == user_data) break; } source = source->next; } UNLOCK_CONTEXT (context); return source;}/** * g_main_context_find_source_by_user_data: * @context: a #GMainContext * @user_data: the user_data for the callback. * * Finds a source with the given user data for the callback. If * multiple sources exist with the same user data, the first * one found will be returned. * * Return value: the source, if one was found, otherwise %NULL **/GSource *g_main_context_find_source_by_user_data (GMainContext *context, gpointer user_data){ GSource *source; if (context == NULL) context = g_main_context_default (); LOCK_CONTEXT (context); source = context->source_list; while (source) { if (!SOURCE_DESTROYED (source) && source->callback_funcs) { GSourceFunc callback; gpointer callback_data = NULL; source->callback_funcs->get (source->callback_data, source, &callback, &callback_data); if (callback_data == user_data) break; } source = source->next; } UNLOCK_CONTEXT (context); return source;}/** * g_source_remove: * @tag: the id of the source to remove. * * Removes the source with the given id from the default main * context. The id of a #GSource is given by g_source_get_id(), * or will be returned by the functions g_source_attach(), * g_idle_add(), g_idle_add_full(), g_timeout_add(), * g_timeout_add_full(), g_io_add_watch, and g_io_add_watch_full(). * * See also g_source_destroy(). * * Return value: %TRUE if the source was found and removed. **/gbooleang_source_remove (guint tag){ GSource *source; g_return_val_if_fail (tag > 0, FALSE); source = g_main_context_find_source_by_id (NULL, tag); if (source) g_source_destroy (source); return source != NULL;}/** * g_source_remove_by_user_data: * @user_data: the user_data for the callback. * * Removes a source from the default main loop context given the user * data for the callback. If multiple sources exist with the same user * data, only one will be destroyed. * * Return value: %TRUE if a source was found and removed. **/gbooleang_source_remove_by_user_data (gpointer user_data){ GSource *source; source = g_main_context_find_source_by_user_data (NULL, user_data); if (source) { g_source_destroy (source); return TRUE; } else return FALSE;}/** * g_source_remove_by_funcs_user_data: * @funcs: The @source_funcs passed to g_source_new() * @user_data: the user data for the callback * * Removes a source from the default main loop context given the * source functions and user data. If multiple sources exist with the * same source functions and user data, only one will be destroyed. * * Return value: %TRUE if a source was found and removed. **/gbooleang_source_remove_by_funcs_user_data (GSourceFuncs *funcs, gpointer user_data){ GSource *source; g_return_val_if_fail (funcs != NULL, FALSE); source = g_main_context_find_source_by_funcs_user_data (NULL, funcs, user_data); if (source) { g_source_destroy (source); return TRUE; } else return FALSE;}/** * g_get_current_time: * @result: #GTimeVal structure in which to store current time. * * Equivalent to the UNIX <function>gettimeofday()</function> function, but portable. **/voidg_get_current_time (GTimeVal *result){#ifndef G_OS_WIN32 struct timeval r; g_return_if_fail (result != NULL); /*this is required on alpha, there the timeval structs are int's not longs and a cast only would fail horribly*/ gettimeofday (&r, NULL); result->tv_sec = r.tv_sec; result->tv_usec = r.tv_usec;#else /* Avoid calling time() except for the first time. * GetTickCount() should be pretty fast and low-level? * I could also use ftime() but it seems unnecessarily overheady. */ static DWORD start_tick = 0; static time_t start_time; DWORD tick; g_return_if_fail (result != NULL); if (start_tick == 0) { start_tick = GetTickCount (); time (&start_time); } tick = GetTickCount (); result->tv_sec = (tick - start_tick) / 1000 + start_time; result->tv_usec = ((tick - start_tick) % 1000) * 1000;#endif}/* Running the main loop *//* HOLDS: context's lock */static voidg_main_dispatch (GMainContext *context){ guint i; for (i = 0; i < context->pending_dispatches->len; i++) { GSource *source = context->pending_dispatches->pdata[i]; context->pending_dispatches->pdata[i] = NULL; g_assert (source); source->flags &= ~G_SOURCE_READY; if (!SOURCE_DESTROYED (source)) { gboolean was_in_call; gpointer user_data = NULL; GSourceFunc callback = NULL; GSourceCallbackFuncs *cb_funcs; gpointer cb_data; gboolean need_destroy; gboolean (*dispatch) (GSource *, GSourceFunc, gpointer); dispatch = source->source_funcs->dispatch; cb_funcs = source->callback_funcs; cb_data = source->callback_data; if (cb_funcs) cb_funcs->ref (cb_data); was_in_call = source->flags & G_HOOK_FLAG_IN_CALL; source->flags |= G_HOOK_FLAG_IN_CALL; if (cb_funcs) cb_funcs->get (cb_data, source, &callback, &user_data); UNLOCK_CONTEXT (context); need_destroy = ! dispatch (source, callback, user_data); LOCK_CONTEXT (context); if (cb_funcs) cb_funcs->unref (cb_data); if (!was_in_call) source->flags &= ~G_HOOK_FLAG_IN_CALL; /* Note: this depends on the fact that we can't switch * sources from one main context to another */ if (need_destroy && !SOURCE_DESTROYED (source)) { g_assert (source->context == context); g_source_destroy_internal (source, context, TRUE); } } SOURCE_UNREF (source, context); } g_ptr_array_set_size (context->pending_dispatches, 0);}/* Holds context's lock */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -