* fhandler.h (class fhandler_socket): Add timeout parameter to wait()
method. * fhandler_socket.cc (fhandler_socket::connect): Use event driven technique (prepare/wait/release) to implement interuptible connect. (fhandler_socket::wait): Add timeout parameter. Allow FD_CONNECT handling. * net.cc (cygwin_connect): Remove braindead workaround for allowing blocking connect. That's entirely in fhandler_socket::connect now.
This commit is contained in:
		| @@ -1,3 +1,14 @@ | ||||
| 2005-10-22  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* fhandler.h (class fhandler_socket): Add timeout parameter to wait() | ||||
| 	method. | ||||
| 	* fhandler_socket.cc (fhandler_socket::connect): Use event driven | ||||
| 	technique (prepare/wait/release) to implement interuptible connect. | ||||
| 	(fhandler_socket::wait): Add timeout parameter.  Allow FD_CONNECT | ||||
| 	handling. | ||||
| 	* net.cc (cygwin_connect): Remove braindead workaround for allowing | ||||
| 	blocking connect.  That's entirely in fhandler_socket::connect now. | ||||
|  | ||||
| 2005-10-22  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* include/cygwin/version.h: Fix typo. | ||||
|   | ||||
| @@ -425,7 +425,7 @@ class fhandler_socket: public fhandler_base | ||||
|   } status; | ||||
|  | ||||
|   bool prepare (HANDLE &event, long event_mask); | ||||
|   int wait (HANDLE event, int flags); | ||||
|   int wait (HANDLE event, int flags, DWORD timeout = 10); | ||||
|   void release (HANDLE event); | ||||
|  | ||||
|  public: | ||||
|   | ||||
| @@ -681,7 +681,20 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen); | ||||
|   if (is_nonblocking ()) | ||||
|     res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen); | ||||
|   else | ||||
|     { | ||||
|       HANDLE evt; | ||||
|       if (prepare (evt, FD_CONNECT)) | ||||
| 	{ | ||||
| 	  res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen); | ||||
| 	  if (res == SOCKET_ERROR | ||||
| 	      && WSAGetLastError () == WSAEWOULDBLOCK) | ||||
| 	     res = wait (evt, 0, INFINITE); | ||||
| 	  release (evt); | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   if (!res) | ||||
|     err = 0; | ||||
| @@ -877,14 +890,14 @@ fhandler_socket::prepare (HANDLE &event, long event_mask) | ||||
| } | ||||
|  | ||||
| int | ||||
| fhandler_socket::wait (HANDLE event, int flags) | ||||
| fhandler_socket::wait (HANDLE event, int flags, DWORD timeout) | ||||
| { | ||||
|   int ret = SOCKET_ERROR; | ||||
|   int wsa_err = 0; | ||||
|   WSAEVENT ev[2] = { event, signal_arrived }; | ||||
|   WSANETWORKEVENTS evts; | ||||
|  | ||||
|   switch (WSAWaitForMultipleEvents (2, ev, FALSE, 10, FALSE)) | ||||
|   switch (WSAWaitForMultipleEvents (2, ev, FALSE, timeout, FALSE)) | ||||
|     { | ||||
|       case WSA_WAIT_TIMEOUT: | ||||
| 	ret = 0; | ||||
| @@ -910,7 +923,14 @@ fhandler_socket::wait (HANDLE event, int flags) | ||||
| 		    break; | ||||
| 		  } | ||||
| 	      } | ||||
| 	    if (evts.lNetworkEvents & FD_READ) | ||||
| 	    if (evts.lNetworkEvents & FD_CONNECT) | ||||
| 	      { | ||||
| 	        if (evts.iErrorCode[FD_CONNECT_BIT]) | ||||
| 		  wsa_err = evts.iErrorCode[FD_CONNECT_BIT]; | ||||
| 		else | ||||
| 		  ret = 0; | ||||
| 	      } | ||||
| 	    else if (evts.lNetworkEvents & FD_READ) | ||||
| 	      { | ||||
| 		if (evts.iErrorCode[FD_READ_BIT]) | ||||
| 		  wsa_err = evts.iErrorCode[FD_READ_BIT]; | ||||
|   | ||||
| @@ -775,56 +775,7 @@ cygwin_connect (int fd, const struct sockaddr *name, int namelen) | ||||
|   if (efault.faulted (EFAULT) || !fh) | ||||
|     res = -1; | ||||
|   else | ||||
|     { | ||||
|       bool was_blocking = false; | ||||
|       if (!fh->is_nonblocking ()) | ||||
| 	{ | ||||
| 	  int nonblocking = 1; | ||||
| 	  fh->ioctl (FIONBIO, &nonblocking); | ||||
| 	  was_blocking = true; | ||||
| 	} | ||||
|       res = fh->connect (name, namelen); | ||||
|       if (was_blocking) | ||||
| 	{ | ||||
| 	  if (res == -1 && get_errno () == EINPROGRESS) | ||||
| 	    { | ||||
| 	      size_t fds_size = howmany (fd + 1, NFDBITS) * sizeof (fd_mask); | ||||
| 	      fd_set *write_fds = (fd_set *) alloca (fds_size); | ||||
| 	      fd_set *except_fds = (fd_set *) alloca (fds_size); | ||||
| 	      memset (write_fds, 0, fds_size); | ||||
| 	      memset (except_fds, 0, fds_size); | ||||
| 	      FD_SET (fd, write_fds); | ||||
| 	      FD_SET (fd, except_fds); | ||||
| 	      res = cygwin_select (fd + 1, NULL, write_fds, except_fds, NULL); | ||||
| 	      if (res > 0 && FD_ISSET (fd, except_fds)) | ||||
| 		{ | ||||
| 		  res = -1; | ||||
| 		  for (;;) | ||||
| 		    { | ||||
| 		      int err; | ||||
| 		      int len = sizeof err; | ||||
| 		      cygwin_getsockopt (fd, SOL_SOCKET, SO_ERROR, | ||||
| 					 (void *) &err, &len); | ||||
| 		      if (err) | ||||
| 			{ | ||||
| 			  set_errno (err); | ||||
| 			  break; | ||||
| 			} | ||||
| 		      low_priority_sleep (0); | ||||
| 		    } | ||||
| 		} | ||||
| 	      else if (res > 0) | ||||
| 		res = 0; | ||||
| 	      else | ||||
| 		{ | ||||
| 		  WSASetLastError (WSAEINPROGRESS); | ||||
| 		  set_winsock_errno (); | ||||
| 		} | ||||
| 	    } | ||||
| 	  int nonblocking = 0; | ||||
| 	  fh->ioctl (FIONBIO, &nonblocking); | ||||
| 	} | ||||
|     } | ||||
|     res = fh->connect (name, namelen); | ||||
|  | ||||
|   syscall_printf ("%d = connect (%d, %p, %d)", res, fd, name, namelen); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user