| I write a client network
program using GIOChannel and GMainLoop on windows. The server program is a
simple sink server, which eats all input. The client program first
connects server, then watches for G_IO_IN and G_IO_OUT and creates a thread which
do g_main_loop_run. At this point G_IO_OUT is surely
ok, the mainloop thread returns from poll and sends one byte to server in
callback. Then the program watches
for G_IO_IN. mainloop thread will block. Then the program sleeps
for a while, and watches for G_IO_OUT. Here, I wish the mainloop
thread to return from poll with G_IO_OUT event. However, mainloop will
block instead of returning from poll. I think the problem is
FD_WRITE will not signaled again until send returns WSAEWOULDBLOCK on windows. Is this a bug of
GMainLoop? Thanks. The client program source
code: ----------------------------------------------------------------------- #include
<winsock2.h> #include
"glib.h" guint source_id; GMutex *mutex; GCond *cond; gboolean recv_cb (GIOChannel
*source,        
 GIOCondition condition,        
 gpointer data) {  
g_assert_not_reached (); } gboolean send_cb (GIOChannel
*source,        
 GIOCondition condition,        
 gpointer data) {   gboolean is_second
= (gboolean) data;   GIOStatus status;   gsize
bytes_written;   gchar c = 'T';   status =
g_io_channel_write_chars (source, &c, 1, &bytes_written, NULL);   g_print ("%s
send_cb write char, status: %d.\n",        
   (is_second ? "Second" : "First"),        
   status);   g_source_remove
(source_id);   source_id = g_io_add_watch
(source,                         
      G_IO_IN | G_IO_ERR,                         
      recv_cb,                         
      NULL);   g_mutex_lock
(mutex);   g_cond_signal
(cond);   g_mutex_unlock
(mutex);   return (TRUE); } int main (int argc, char
**argv) {   WSADATA wsa_data;   SOCKET s;   struct sockaddr_in
addr;   gint addrlen =
sizeof (addr);   GIOChannel
*channel;   GMainLoop *loop;   GThread *thread;      g_assert
(WSAStartup(0x0202, &wsa_data) == 0);   g_thread_init
(NULL);   mutex = g_mutex_new
();   cond = g_cond_new
();      s = socket
(AF_INET, SOCK_STREAM, 0);   g_assert (s !=
INVALID_SOCKET);      g_assert
(WSAStringToAddress ("155.69.149.175:5555",                                  
AF_INET,                                  
NULL,                                  
(PSOCKADDR)&addr,                                  
&addrlen)        
    != SOCKET_ERROR);   g_assert (connect
(s, (struct sockaddr *) &addr, sizeof (addr)) != SOCKET_ERROR);   channel =
g_io_channel_win32_new_socket (s);   loop =
g_main_loop_new (NULL, FALSE);   g_assert (loop);   thread =
g_thread_create ((GThreadFunc) g_main_loop_run,                         
    loop,                         
    TRUE,                         
    NULL);   g_assert (thread);   g_mutex_lock
(mutex);   source_id =
g_io_add_watch (channel,                         
      G_IO_IN | G_IO_ERR | G_IO_OUT,                         
      send_cb,                         
      (gpointer) FALSE);   g_cond_wait (cond,
mutex);   g_mutex_unlock
(mutex);   g_usleep (500000);   g_source_remove
(source_id);   g_usleep (500000);   g_mutex_lock
(mutex);   source_id =
g_io_add_watch (channel,                         
      G_IO_IN | G_IO_ERR | G_IO_OUT,                         
      send_cb,                         
      (gpointer) TRUE);   g_cond_wait (cond,
mutex);   g_mutex_unlock
(mutex);   g_main_loop_quit
(loop);   g_thread_join
(thread);   return (0); } |