Блокировка потоков GMainLoop и TCP Listen

Мне нужна ваша помощь.

У меня есть основной цикл GMainLoop с прикрепленным обратным вызовом тайм-аута:

MainLoop = g_main_loop_new(NULL, FALSE);
g_timeout_add_seconds(Interval, TimeoutCallback, (gpointer) Rec);
g_main_loop_run(MainLoop);

И слушай сокет:

int ControlServer::GStart()
{
int listenfd;
GIOChannel *in;
socklen_t addr_len;
listenfd = TcpListen(host, port, &addr_len);
in = g_io_channel_unix_new(listenfd);
g_io_add_watch(in, G_IO_IN, (GIOFunc) Handler, (gpointer) Rec);
g_io_channel_unref(in);
return 0;
}

Все хорошо и функция тайм-аута работает правильно, пока любой клиент не подключен к прослушиваемому сокету. После подключения тайм-аут не работает все время, что клиент подключен. Я думаю, что это связано с потоками, как в документации GLib по умолчанию GMainContext все действия, выполняемые в одном потоке. И я изменил код с этим:

int ControlServer::GThStart()
{
int listenfd;
socklen_t addr_len;
GIOChannel *Channel;
GSource *Source;
GMainContext *Context;

listenfd = TcpListen(host, port, &addr_len);
Channel = g_io_channel_unix_new(listenfd);
Source = g_io_create_watch(Channel, G_IO_IN);
g_source_set_callback(Source, (GSourceFunc) Handler, (gpointer) Rec, NULL);
Context = g_main_context_new();
g_source_attach(Source, Context);
g_source_unref(Source);
return 0;
}

Но теперь сокет прослушивается, но никакие клиенты не могут подключиться к нему, и функция обработчика никогда не вызывается.

Код обработчика ниже:

bool ControlServer::Handler(GIOChannel *in, GIOCondition condition, gpointer data)
{
Recorder *Rec = (Recorder *) data;
struct sockaddr_storage income;
int insock, newsock;
socklen_t income_len;
struct sockaddr peer;
socklen_t size;
Access *access;

insock = g_io_channel_unix_get_fd(in);
income_len = sizeof(income);
newsock = accept(insock, (struct sockaddr *) &income, &income_len);
size = sizeof(peer);
getpeername(newsock, &peer, &size);
struct sockaddr_in *ipv4 = (struct sockaddr_in *) &peer;
access = new Access(newsock, ipv4, MAXN);

access->Cycle(Rec);

delete access;
return true;
}

Класс «Доступ» проверяет права клиента и выполняет обмен протоколами по бесконечному циклу реализации, пока клиент или сервер не закрывают соединение.

  do
{
result = DoCycle(Rec);
sprintf(str, "DEBUG: DoCycle(Rec) returns '%d'\n", result);
AppendLog(str, class_name, DEBUG);
} while (result != -1);

DoCycle () возвращает -1 только тогда, когда соединение закрыто или произошла ошибка при обмене данными через TCP.

Что не так?
Спасибо!

1

Решение

Проблема в функции int ControlServer::GThStart(), вы должны добавить GSource к GMainContext вашей GMainLoop, не в новый контекст, попробуйте это с:

g_source_attach(Source,g_main_loop_get_context(MainLoop));
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]