comparison src/w32.c @ 71899:6772d0603863

(pfn_WSACreateEvent, pfn_WSACloseEvent): New func ptrs. (init_winsock): Load them. Use ws2_32.dll. (sys_listen): Undo last change. Just set FILE_LISTEN flag. (sys_accept): Undo last change. Instead, set child status to STATUS_READ_ACKNOWLEDGED and reset char_avail event so next sys_select will wakeup the reader thread. (_sys_wait_accept): New function used by reader thread to wait for an incoming connection on a server socket.
author Kim F. Storm <storm@cua.dk>
date Fri, 14 Jul 2006 14:18:40 +0000
parents 2385a5c8186c
children 7b3a19a8bfdb 8a8e69664178
comparison
equal deleted inserted replaced
71898:5400fa001771 71899:6772d0603863
2699 /* function pointers for relevant socket functions */ 2699 /* function pointers for relevant socket functions */
2700 int (PASCAL *pfn_WSAStartup) (WORD wVersionRequired, LPWSADATA lpWSAData); 2700 int (PASCAL *pfn_WSAStartup) (WORD wVersionRequired, LPWSADATA lpWSAData);
2701 void (PASCAL *pfn_WSASetLastError) (int iError); 2701 void (PASCAL *pfn_WSASetLastError) (int iError);
2702 int (PASCAL *pfn_WSAGetLastError) (void); 2702 int (PASCAL *pfn_WSAGetLastError) (void);
2703 int (PASCAL *pfn_WSAEventSelect) (SOCKET s, HANDLE hEventObject, long lNetworkEvents); 2703 int (PASCAL *pfn_WSAEventSelect) (SOCKET s, HANDLE hEventObject, long lNetworkEvents);
2704 HANDLE (PASCAL *pfn_WSACreateEvent) (void);
2705 int (PASCAL *pfn_WSACloseEvent) (HANDLE hEvent);
2704 int (PASCAL *pfn_socket) (int af, int type, int protocol); 2706 int (PASCAL *pfn_socket) (int af, int type, int protocol);
2705 int (PASCAL *pfn_bind) (SOCKET s, const struct sockaddr *addr, int namelen); 2707 int (PASCAL *pfn_bind) (SOCKET s, const struct sockaddr *addr, int namelen);
2706 int (PASCAL *pfn_connect) (SOCKET s, const struct sockaddr *addr, int namelen); 2708 int (PASCAL *pfn_connect) (SOCKET s, const struct sockaddr *addr, int namelen);
2707 int (PASCAL *pfn_ioctlsocket) (SOCKET s, long cmd, u_long *argp); 2709 int (PASCAL *pfn_ioctlsocket) (SOCKET s, long cmd, u_long *argp);
2708 int (PASCAL *pfn_recv) (SOCKET s, char * buf, int len, int flags); 2710 int (PASCAL *pfn_recv) (SOCKET s, char * buf, int len, int flags);
2768 pfn_SetHandleInformation = NULL; 2770 pfn_SetHandleInformation = NULL;
2769 pfn_SetHandleInformation 2771 pfn_SetHandleInformation
2770 = (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"), 2772 = (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"),
2771 "SetHandleInformation"); 2773 "SetHandleInformation");
2772 2774
2773 winsock_lib = LoadLibrary ("wsock32.dll"); 2775 winsock_lib = LoadLibrary ("Ws2_32.dll");
2774 2776
2775 if (winsock_lib != NULL) 2777 if (winsock_lib != NULL)
2776 { 2778 {
2777 /* dynamically link to socket functions */ 2779 /* dynamically link to socket functions */
2778 2780
2782 2784
2783 LOAD_PROC( WSAStartup ); 2785 LOAD_PROC( WSAStartup );
2784 LOAD_PROC( WSASetLastError ); 2786 LOAD_PROC( WSASetLastError );
2785 LOAD_PROC( WSAGetLastError ); 2787 LOAD_PROC( WSAGetLastError );
2786 LOAD_PROC( WSAEventSelect ); 2788 LOAD_PROC( WSAEventSelect );
2789 LOAD_PROC( WSACreateEvent );
2790 LOAD_PROC( WSACloseEvent );
2787 LOAD_PROC( socket ); 2791 LOAD_PROC( socket );
2788 LOAD_PROC( bind ); 2792 LOAD_PROC( bind );
2789 LOAD_PROC( connect ); 2793 LOAD_PROC( connect );
2790 LOAD_PROC( ioctlsocket ); 2794 LOAD_PROC( ioctlsocket );
2791 LOAD_PROC( recv ); 2795 LOAD_PROC( recv );
3296 { 3300 {
3297 int rc = pfn_listen (SOCK_HANDLE (s), backlog); 3301 int rc = pfn_listen (SOCK_HANDLE (s), backlog);
3298 if (rc == SOCKET_ERROR) 3302 if (rc == SOCKET_ERROR)
3299 set_errno (); 3303 set_errno ();
3300 else 3304 else
3301 { 3305 fd_info[s].flags |= FILE_LISTEN;
3302 fd_info[s].flags |= FILE_LISTEN;
3303 pfn_WSAEventSelect (SOCK_HANDLE (s), fd_info[s].cp->char_avail, FD_ACCEPT);
3304 }
3305 return rc; 3306 return rc;
3306 } 3307 }
3307 h_errno = ENOTSOCK; 3308 h_errno = ENOTSOCK;
3308 return SOCKET_ERROR; 3309 return SOCKET_ERROR;
3309 } 3310 }
3340 3341
3341 check_errno (); 3342 check_errno ();
3342 if (fd_info[s].flags & FILE_LISTEN) 3343 if (fd_info[s].flags & FILE_LISTEN)
3343 { 3344 {
3344 SOCKET t = pfn_accept (SOCK_HANDLE (s), addr, addrlen); 3345 SOCKET t = pfn_accept (SOCK_HANDLE (s), addr, addrlen);
3345 if (t != INVALID_SOCKET) 3346 int fd = -1;
3346 { 3347 if (t == INVALID_SOCKET)
3347 int fd = socket_to_fd (t); 3348 set_errno ();
3348 if (fd >= 0) 3349 else
3349 pfn_WSAEventSelect (SOCK_HANDLE (fd), fd_info[fd].cp->char_avail, FD_READ | FD_CLOSE); 3350 fd = socket_to_fd (t);
3350 return fd; 3351
3351 } 3352 fd_info[s].cp->status = STATUS_READ_ACKNOWLEDGED;
3352 3353 ResetEvent (fd_info[s].cp->char_avail);
3353 set_errno (); 3354 return fd;
3354 return -1;
3355 } 3355 }
3356 h_errno = ENOTSOCK; 3356 h_errno = ENOTSOCK;
3357 return -1; 3357 return -1;
3358 } 3358 }
3359 3359
3647 3647
3648 if (rc == sizeof (char)) 3648 if (rc == sizeof (char))
3649 cp->status = STATUS_READ_SUCCEEDED; 3649 cp->status = STATUS_READ_SUCCEEDED;
3650 else 3650 else
3651 cp->status = STATUS_READ_FAILED; 3651 cp->status = STATUS_READ_FAILED;
3652
3653 return cp->status;
3654 }
3655
3656 int _sys_wait_accept (int fd)
3657 {
3658 HANDLE hEv;
3659 child_process * cp;
3660 int rc;
3661
3662 if (fd < 0 || fd >= MAXDESC)
3663 return STATUS_READ_ERROR;
3664
3665 cp = fd_info[fd].cp;
3666
3667 if (cp == NULL || cp->fd != fd || cp->status != STATUS_READ_READY)
3668 return STATUS_READ_ERROR;
3669
3670 cp->status = STATUS_READ_FAILED;
3671
3672 hEv = pfn_WSACreateEvent ();
3673 rc = pfn_WSAEventSelect (SOCK_HANDLE (fd), hEv, FD_ACCEPT);
3674 if (rc != SOCKET_ERROR)
3675 {
3676 rc = WaitForSingleObject (hEv, INFINITE);
3677 pfn_WSAEventSelect (SOCK_HANDLE (fd), NULL, 0);
3678 pfn_WSACloseEvent (hEv);
3679 if (rc == WAIT_OBJECT_0)
3680 cp->status = STATUS_READ_SUCCEEDED;
3681 }
3652 3682
3653 return cp->status; 3683 return cp->status;
3654 } 3684 }
3655 3685
3656 int 3686 int