Подробности
[В начало]
Проблема в реализации № D0006
Краткое описание
Вызов функции "g_main_context_pending" увеличивает количество ссылок на готовые к обработке источники событий
Подробное описание
Вызов функции g_main_context_pending увеличивает количество ссылок на готовые источники событий из-за внутреннего вызова функции g_main_context_check. Функция g_main_context_check вызывается со значением параметра "dispatch=FALSE". Обычно при вызове функции g_main_context_check со значением параметра "dispatch=TRUE" внутренний вызов g_main_context_dispatch уменьшает количество ссылок на указанные источники.
Раздел стандарта
Linux Standard Base Desktop Specification 3.1, Chapter 12. Libraries, 12.2 Interfaces for libglib-2.0; http://www.gtk.org/api/2.6/glib/glib-The-Main-Event-Loop.html#g-main-context-pending
Способ воспроизведения
- К контексту подсоединяются 4 источника событий, двое с численными значениями приоритета равным "-1" и двое других с "1" и "2" соответственно.
- Первые два источника помечаются как "готовые" после внутреннего вызова "g_main_context_check" и в то же самое время количество ссылок на них увеличивается.
(process:7320): GLib-WARNING **: gmain.c:1417: ref_count == 0, but source is still attached to a context! (process:7320): GLib-WARNING **: gmain.c:1417: ref_count == 0, but source is still attached to a context!Отсутствие предупреждений при запуске примера указывает на то, что в результате вызова функции "g_main_context_pending" количество ссылок на готовые источники событий увеличиваются.
Пример
#include <stdio.h> #include <glib.h> int mci_CallbackCount = 0; int mci_PrepareCount = 0; int mci_CheckCount = 0; int mci_DispatchCount = 0; int mci_PollCount = 0; gboolean mci_CallbackRetValue = FALSE; gboolean mci_PrepareRetValue = FALSE; gboolean mci_CheckRetValue = FALSE; gint mci_Timeout = 0; int mci_cb_status[4] = {0, 0, 0, 0}; gboolean mci_callback_P1(gpointer data) {mci_cb_status[0]++; return mci_CallbackRetValue;} gboolean mci_callback_P2(gpointer data) {mci_cb_status[1]++; return mci_CallbackRetValue;} gboolean mci_callback_P3(gpointer data) {mci_cb_status[2]++; return mci_CallbackRetValue;} gboolean mci_callback_P4(gpointer data) {mci_cb_status[3]++; return mci_CallbackRetValue;} gboolean (*mci_cbArray[4])(gpointer data) = {mci_callback_P1, mci_callback_P2, mci_callback_P3, mci_callback_P4}; gboolean mci_prepare(GSource *source, gint *timeout_) {mci_PrepareCount++;*timeout_=mci_Timeout;return mci_PrepareRetValue; } gboolean mci_check(GSource *source) {mci_CheckCount++;return mci_CheckRetValue;} gboolean mci_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) {mci_DispatchCount++;return callback(user_data);} GSourceFuncs mci_funcs = { mci_prepare, mci_check, mci_dispatch, NULL }; int mci_status = 0; GSource* mci_SourceArray[4] = {NULL, NULL, NULL, NULL}; int main() { printf("Glib version %d.%d.%d \n\n", glib_major_version, glib_minor_version, glib_micro_version ); mci_Timeout = -1; mci_status = 0; mci_CallbackRetValue = TRUE; mci_PrepareRetValue = FALSE; mci_CheckRetValue = TRUE; GMainContext *mcp_MainContext = g_main_context_new(); for(int i = 0; i < 4; ++i) { GSource *mci_source = (GSource*)g_source_new(&mci_funcs, sizeof (GSource)); mci_SourceArray[i] = mci_source; g_source_set_callback (mci_source, mci_cbArray[i], NULL, NULL); g_source_set_priority(mci_source, i < 2 ? -1 : i - 1); g_source_attach(mci_source, mcp_MainContext); g_source_unref(mci_source); } g_main_context_pending(mcp_MainContext); /* * if g_main_context_pending() would not have called here, after the * following lines "g_main_context_unref()" would give 2 warning like: * * -------- * (process:7320): GLib-WARNING **: gmain.c:1417: ref_count == 0, * but source is still attached to a context! * * (process:7320): GLib-WARNING **: gmain.c:1417: ref_count == 0, * but source is still attached to a context! * -------- * * which means that reference count for ready sources was increased upon * calling "g_main_context_pending()". * * */ for(int i = 0; i < 2; ++i) { g_source_unref(mci_SourceArray[i]); } if(mcp_MainContext) g_main_context_unref(mcp_MainContext); return 0; }
Компонент
gtk-glib 2.6.2 or later
Принято
Gnome Bugzilla 479787
[В начало]