RE: Is this a bug of GMainLoop?
- From: "#YU KUAN#" <yukuan pmail ntu edu sg>
- To: "Tor Lillqvist" <tml iki fi>
- Cc: gtk-devel-list gnome org
- Subject: RE: Is this a bug of GMainLoop?
- Date: Thu, 15 May 2008 11:58:29 +0800
Thanks for your reply.
Yes, it works in linux.
The following is the log by setting G_IO_WIN32_DEBUG:
1 g_io_channel_win32_new_socket: sockfd=1880
2 g_io_win32_sock_set_flags: NONBLOCK
3 g_io_win32_sock_create_watch: sock=1880 handle=0x73c condition={IN|OUT|ERR}
4 g_io_win32_prepare: WSAEventSelect(1880, 0x73c, {READ|WRITE|ACCEPT|CONNECT|CLOSE}
5 g_io_win32_check: WSAEnumNetworkEvents (1880, 0x73c) revents={IN|OUT} condition={IN|OUT|ERR} events={WRITE|CONNECT}
6 g_io_win32_dispatch: pollfd.revents=OUT condition=IN|OUT|ERR result=OUT
First send_cb write char, status: 1.
7 g_io_win32_sock_create_watch: sock=1880 handle=0x73c condition={IN|ERR}
8 g_io_win32_finalize: channel is for sock=1880
9 g_io_win32_prepare: WSAEventSelect(1880, 0x73c, {READ|ACCEPT|CLOSE}
10 g_io_win32_check: WSAEnumNetworkEvents (1880, 0x73c) revents={IN} condition={IN|ERR} events={}
11 g_io_win32_check: WSAEventSelect(1880, 0x73c, {})
12 g_io_win32_check: ResetEvent(0x73c)
13 g_io_win32_prepare: WSAEventSelect(1880, 0x73c, {READ|ACCEPT|CLOSE}
14 g_io_win32_finalize: channel is for sock=1880
15 g_io_win32_sock_create_watch: sock=1880 handle=0x73c condition={IN|OUT|ERR}
16 g_io_win32_prepare: WSAEventSelect(1880, 0x73c, {READ|WRITE|ACCEPT|CONNECT|CLOSE}
I think the problem is: line 5 shows the g_poll returns FD_WRITE, and according to
if (watch->pollfd.revents != 0 &&
events.lNetworkEvents == 0 &&
!(channel->event_mask & FD_WRITE))
{
...
ResetEvent ((HANDLE) watch->pollfd.fd);
...
}
The event will not be reset. Since it is not reset, the g_poll will signal this FD_WRITE event again. This is shown in line 10: revents={IN}, but events={}.
And in line 12, the event is reset. So the next g_poll will check FD_WRITE event of the socket. However, according to msdn documentation of WSAEventSelect,
----------------------------
The FD_WRITE network event is handled slightly differently. An FD_WRITE network event is recorded when a socket is first connected with connect/WSAConnect or accepted with accept/WSAAccept, and then after a send fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, an application can assume that sends are possible starting from the first FD_WRITE network event setting and lasting until a send returns WSAEWOULDBLOCK. After such a failure the application will find out that sends are again possible when an FD_WRITE network event is recorded and the associated event object is set.
----------------------------
The FD_WRITE event of the socket will not be signaled. As a result, g_poll will block and not return.
I add the following in line giowin32.c:841, the program can work.
channel->event_mask = event_mask;
#if 0
channel->event = watch->pollfd.fd;
#endif
channel->last_events = 1;
+ if (event_mask & FD_WRITE && !channel->write_would_have_blocked)
+ WSASetEvent (watch->pollfd.fd);
}
break;
But I don't know whether it affects other part of glib program.
Regards,
YuKuan
-----Original Message-----
From: tlillqvist gmail com [mailto:tlillqvist gmail com] On Behalf Of Tor Lillqvist
Sent: 星期四, 15 五月, 2008 AM 1:53
To: #YU KUAN#
Cc: gtk-devel-list gnome org
Subject: Re: Is this a bug of GMainLoop?
Have you, by the way, verified that the corresponding program works on Linux?
--tml
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]