diff -ru old/giowin32.c new/giowin32.c
--- old/giowin32.c	Fri May 12 15:20:36 2006
+++ new/giowin32.c	Sat Sep 23 23:18:39 2006
@@ -113,6 +113,7 @@
   int event_mask;
   int last_events;
   int event;
+  gboolean FD_WRITE_received;
   gboolean write_would_have_blocked;
 };
 
@@ -355,6 +356,7 @@
   channel->event_mask = 0;
   channel->last_events = 0;
   channel->event = 0;
+  channel->FD_WRITE_received = FALSE;
   channel->write_would_have_blocked = FALSE;
   InitializeCriticalSection (&channel->mutex);
 }
@@ -827,10 +829,21 @@
 	  if (channel->debug)
 	    g_print ("g_io_win32_prepare: WSAEventSelect(%d, %#x, {%s}\n",
 		     channel->fd, watch->pollfd.fd,
-		     event_mask_to_string (event_mask));
+		     event_mask_to_string (channel->FD_WRITE_received ? event_mask : event_mask | FD_WRITE));
+	/*
+	We have to receive the first FD_WRITE even if the user didn't request it to be
+	able to set G_IO_OUT later correctly. This will make sure, user callback will
+	be notified of G_IO_OUT if socket is ready and the last send
+        didn't return WSAEWOULDBLOCK
+	*/
 	  if (WSAEventSelect (channel->fd, (HANDLE) watch->pollfd.fd,
-			      event_mask) == SOCKET_ERROR)
+			      channel->FD_WRITE_received ? event_mask : event_mask | FD_WRITE ) == SOCKET_ERROR) {
 	    ;			/* What? */
+	    /* At least print something to debug ...*/
+	    g_print ("g_io_win32_prepare: WSAEventSelect SOCKET_ERROR (%d, %#x, {%s}\n",
+		     channel->fd, watch->pollfd.fd,
+		     event_mask_to_string (channel->FD_WRITE_received ? event_mask : event_mask | FD_WRITE));
+        }
 	  channel->event_mask = event_mask;
 #if 0
 	  channel->event = watch->pollfd.fd;
@@ -874,13 +887,16 @@
       return ((watch->pollfd.revents | buffer_condition) & watch->condition);
 
     case G_IO_WIN32_SOCKET:
-      if (channel->last_events & FD_WRITE)
+/*      If we get one FD_WRITE we could get stuck here as 
+        channel->last_events would not be updated.
+        
+        if (channel->last_events & FD_WRITE)
 	{
 	  if (channel->debug)
 	    g_print ("g_io_win32_check: sock=%d event=%#x last_events has FD_WRITE\n",
 		     channel->fd, watch->pollfd.fd);
 	}
-      else
+      else*/
 	{
 	  WSAEnumNetworkEvents (channel->fd, 0, &events);
 
@@ -910,13 +926,35 @@
       watch->pollfd.revents = 0;
       if (channel->last_events & (FD_READ | FD_ACCEPT))
 	watch->pollfd.revents |= G_IO_IN;
-      if (channel->last_events & (FD_WRITE | FD_CONNECT))
+	
+      if (channel->last_events & FD_WRITE) {
 	watch->pollfd.revents |= G_IO_OUT;
+        channel->FD_WRITE_received = TRUE;
+        g_print ("g_io_win32_check: channel->FD_WRITE_received = TRUE;\n");	
+        }else
+      if (channel->last_events & FD_CONNECT) {
+	watch->pollfd.revents |= G_IO_OUT;
+        }
+
+/*    fix by yaro  
       if (watch->pollfd.revents == 0 && (channel->last_events & (FD_CLOSE)))
+	watch->pollfd.revents |= G_IO_HUP;*/
+	
+	/*  We have to dispatch FD_CLOSE too, because WSAEnumNetworkEvents automatically
+      clears network events and FD_CLOSE would be "lost". Let the receiver
+      decide what to do if both G_IO_IN & G_IO_HUP are received. 2nd possible implementation
+      would be to dispatch G_IO_IN first and then G_IO_HUP.
+	*/
+      if (channel->last_events & (FD_CLOSE))
 	watch->pollfd.revents |= G_IO_HUP;
 
-      if (!channel->write_would_have_blocked && (channel->event_mask & FD_WRITE))
-	watch->pollfd.revents |= G_IO_OUT; /* This sucks but... */
+      /* G_IO_OUT should be sent only once we receive first FD_WRITE event. To make sure
+      we don't miss it (could happen if user didn't ask for it), we have to set
+      WSAEventSelect to listen for FD_WRITE until we get the first FD_WRITE even
+      if the user doesn't ask for it*/
+      if (channel->FD_WRITE_received && !channel->write_would_have_blocked && (channel->event_mask & FD_WRITE)) {
+	watch->pollfd.revents |= G_IO_OUT; /* This sucks but... - not anymore !!*/
+      }
 
       return ((watch->pollfd.revents | buffer_condition) & watch->condition);
 
@@ -1889,6 +1927,11 @@
 {
   GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
   GIOChannel *channel = (GIOChannel *)win32_channel;
+  fd_set writefds;
+  struct timeval timeout;
+
+  timeout.tv_sec = 0;/* This is for non blocking select*/
+  timeout.tv_usec = 0;
 
   g_io_channel_init (channel);
   g_io_channel_win32_init (win32_channel);
@@ -1901,6 +1944,14 @@
   channel->is_readable = TRUE;
   channel->is_writeable = TRUE;
   channel->is_seekable = FALSE;
+
+  FD_ZERO(&writefds);
+  FD_SET(socket, &writefds);
+  /* in winsock select, 1st parameter is ignored*/
+  if(select(0, NULL, &writefds, NULL, &timeout) > 0) {
+    g_print ("g_io_channel_win32_new_socket: channel->FD_WRITE_received = TRUE;\n");
+    win32_channel->FD_WRITE_received = TRUE;
+  }
 
   return channel;
 }
