Details
[Home]
Issue of the Implementation # D0004
Brief
The "g_main_context_check" interface ignores it's "max_priority" parameter
Detailed Description
Documentation states that "max_priority" input parameter of the interface g_main_context_check determines "the maximum numerical priority of sources to check". This means that all the sources with numerical priority higher than "max_priority" should not be checked, although in the implementation this parameter is ignored.
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-check
Reproducing
- 3 sources are attached to the context, with the priorities {-1, 0, 1}
- All the sources, added to the context return FALSE upon prepare*() and check*() calls
- Verify that return value of the g_main_context_check() is FALSE
- Verify that the only source, that was checked was the one with priority -1, [max_priority == -1]
Example
#include <unistd.h>
#include <stdio.h>
#include <glib.h>
int iter_CallbackCount = 0;
int iter_PrepareCount = 0;
int iter_CheckCount = 0;
int iter_DispatchCount = 0;
int iter_PollCount = 0;
gboolean iter_CallbackRetValue = FALSE;
gboolean iter_PrepareRetValue = FALSE;
gboolean iter_CheckRetValue = FALSE;
gint iter_Timeout = 0;
gboolean iter_callback(gpointer data)
{iter_CallbackCount++;return iter_CallbackRetValue;}
gboolean iter_prepare(GSource *source, gint *timeout_)
{iter_PrepareCount++;*timeout_=iter_Timeout;return iter_PrepareRetValue; }
gboolean iter_check(GSource *source)
{iter_CheckCount++;return iter_CheckRetValue;}
gboolean iter_dispatch(GSource *source, GSourceFunc callback,
gpointer user_data)
{iter_DispatchCount++;return callback(user_data);}
GSourceFuncs iter_funcs =
{
iter_prepare,
iter_check,
iter_dispatch,
NULL
};
int iter_init_sources(GMainContext* it_mainContext, GPollFD* fd_a,
GSource** source_a, int pipe_a[3][2], gboolean eq_priority)
{
for(int i = 0; i < 3; ++i)
{
if(pipe(pipe_a[i]) != 0)
{
return -1;
}
fd_a[i].fd = pipe_a[i][0];
fd_a[i].events = G_IO_IN | G_IO_HUP | G_IO_ERR;
fd_a[i].revents = 0;
source_a[i] = g_source_new(&iter_funcs, sizeof (GSource));
if(source_a[i] == NULL)
return -2;
g_source_set_callback (source_a[i], iter_callback, NULL, NULL);
g_source_set_priority(source_a[i], eq_priority ?
G_PRIORITY_DEFAULT: i - 1);
g_source_add_poll(source_a[i], &fd_a[i]);
g_source_attach(source_a[i], it_mainContext);
g_source_unref(source_a[i]);
}
return 0;
}
void iter_release_resources(GMainContext* it_mainContext, GSource** source_a,
int pipe_a[3][2])
{
for(int i = 0; i < 3; ++i)
{
close(pipe_a[i][0]);
close(pipe_a[i][1]);
}
if(it_mainContext){
g_main_context_unref(it_mainContext);
}
}
GMainContext *chk_mainContext;
int main()
{
chk_mainContext = g_main_context_new();
int pipe_a[3][2] = {{0}};
GPollFD fd_a[3];
GSource* source_a[3];
iter_init_sources(chk_mainContext, fd_a, source_a, pipe_a, FALSE);
GPollFD qfd_a[10];
iter_PrepareCount = 0;
iter_PrepareRetValue = FALSE;
iter_Timeout = 8;
int priority = 0;
g_main_context_prepare (chk_mainContext, &priority);
gint timeout;
gint recordCount = g_main_context_query(chk_mainContext,
2,
&timeout,
qfd_a,
1);
iter_CheckCount = 0;
iter_CheckRetValue = FALSE;
gint checkRetValue = g_main_context_check(chk_mainContext, -1, qfd_a,
recordCount);
if(!(checkRetValue == FALSE && iter_CheckCount == 1))
{
char *message = checkRetValue == TRUE?
"g_main_context_check: returned TRUE, although there is no source, "\
"ready to be dispatched.\n"
: "g_main_context_check: sources with higher numerical priority than"\
"specified are being checked.\n";
printf(message);
}
iter_release_resources(chk_mainContext, source_a, pipe_a);
return 0;
}
Component
gtk-glib 2.6.2 or later
Accepted
Gnome Bugzilla 477659
[Home]