Подробности
[В начало]
Проблема в реализации № D0004
Краткое описание
Функция "g_main_context_check" игнорирует входной параметр "max_priority"
Подробное описание
Судя по документации параметр "max_priority" функции g_main_context_check задает: "the maximum numerical priority of sources to check". Это означает что все источники численным значением приоритета выше значения "max_priority" не подлежат проверке, в то время как в реализации данный параметр не оказывает никакого влияния на функциональность.
Раздел стандарта
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
Способ воспроизведения
- К контексту подключаются 3 источника событий с численными значениями приоритетов {-1, 0, 1}
- Соответствующие функции источников заданы таким образом, что возвращают "FALSE" при вызовах "prepare*()" и "check*()"
- Проверяется чтобы возвращаемое значения после вызова "g_main_context_check()" было "FALSE"
- При правильном поведении единственным источником, проверенным после этого вызова должен был быть источник с численным значением приоритета равным "-1"
Пример
#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; }
Компонент
gtk-glib 2.6.2 or later
Принято
Gnome Bugzilla 477659
[В начало]