Details
[Home]
Issue of the Implementation # D0006
Brief
Calling "g_main_context_pending" increases reference count for the ready sources
Detailed Description
Calling g_main_context_pending increases reference count for the ready sources, in the internal call to g_main_context_check. This function calls internal g_main_context_iterate, with "dispatch" parameter set to "FALSE". Normally, whenever g_main_context_iterate is called with "dispatch" parameter set to "TRUE", internal call of g_main_context_dispatch decreases the reference count of the dispatched sources.
Problem location(s) in the standard
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
Reproducing
- 4 sources are attached to the newly created context, two of which with priority "-1" and two others with "1" and "2".
- First two sources will be marked as "READY" after internal call of "g_main_context_check" and reference count for them will be increased.
(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!
The absence of these warnings upon invocation of the sample shows that reference count for ready sources was increased during the call to "g_main_context_pending".
Example
#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;
}
Component
gtk-glib 2.6.2 or later
Accepted
Gnome Bugzilla 479787
[Home]