Winsock rewrite. Sockets are now proper win32 handles.

Internal structures are now really internal.
This commit is contained in:
Ove Kaaven 1999-10-23 16:53:34 +00:00 committed by Alexandre Julliard
parent 42a474ed65
commit f45608f639
10 changed files with 638 additions and 878 deletions

View File

@ -59,3 +59,5 @@ type win16
115 pascal WSAStartup(word ptr) WSAStartup16 115 pascal WSAStartup(word ptr) WSAStartup16
116 pascal WSACleanup() WSACleanup 116 pascal WSACleanup() WSACleanup
151 pascal16 __WSAFDIsSet(word ptr) __WSAFDIsSet16 151 pascal16 __WSAFDIsSet(word ptr) __WSAFDIsSet16
1999 pascal DllEntryPoint(long word word word long word) WINSOCK_LibMain

View File

@ -93,8 +93,7 @@ typedef struct _TDB
DWORD compat_flags WINE_PACKED; /* 4e Compatibility flags */ DWORD compat_flags WINE_PACKED; /* 4e Compatibility flags */
BYTE unused4[2]; /* 52 */ BYTE unused4[2]; /* 52 */
struct _TEB *teb; /* 54 Pointer to thread database */ struct _TEB *teb; /* 54 Pointer to thread database */
struct _WSINFO *pwsi; /* 58 Socket control struct */ BYTE unused5[8]; /* 58 */
BYTE unused5[4]; /* 5B */
HANDLE16 hPDB; /* 60 Selector of PDB (i.e. PSP) */ HANDLE16 hPDB; /* 60 Selector of PDB (i.e. PSP) */
SEGPTR dta WINE_PACKED; /* 62 Current DTA */ SEGPTR dta WINE_PACKED; /* 62 Current DTA */
BYTE curdrive; /* 66 Current drive */ BYTE curdrive; /* 66 Current drive */

View File

@ -279,10 +279,10 @@ typedef struct WSAData {
#define WS_FD_CLOSE 0x0020 #define WS_FD_CLOSE 0x0020
#define WS_FD_LISTENING 0x10000000 /* internal per-socket flags */ #define WS_FD_LISTENING 0x10000000 /* internal per-socket flags */
#define WS_FD_INACTIVE 0x20000000 #define WS_FD_NONBLOCKING 0x20000000
#define WS_FD_CONNECTED 0x40000000 #define WS_FD_CONNECTED 0x40000000
#define WS_FD_RAW 0x80000000 #define WS_FD_RAW 0x80000000
#define WS_FD_NONBLOCKING 0x01000000 #define WS_FD_SERVEVENT 0x01000000
#define WS_FD_INTERNAL 0xFFFF0000 #define WS_FD_INTERNAL 0xFFFF0000
/* /*
@ -534,73 +534,6 @@ typedef struct timeval TIMEVAL, *PTIMEVAL, *LPTIMEVAL;
*/ */
#define WSAGETSELECTERROR(lParam) HIWORD(lParam) #define WSAGETSELECTERROR(lParam) HIWORD(lParam)
/* ----------------------------------- internal structures */
/* ws_... struct conversion flags */
#define WS_DUP_LINEAR 0x0001
#define WS_DUP_NATIVE 0x0000 /* not used anymore */
#define WS_DUP_OFFSET 0x0002 /* internal pointers are offsets */
#define WS_DUP_SEGPTR 0x0004 /* internal pointers are SEGPTRs */
/* by default, internal pointers are linear */
typedef struct __sop /* WSAAsyncSelect() control struct */
{
struct __sop *next, *prev;
struct __ws* pws;
HWND hWnd;
UINT uMsg;
} ws_select_op;
typedef struct __ws /* socket */
{
int fd;
unsigned flags;
ws_select_op* psop;
} ws_socket;
#define WS_MAX_SOCKETS_PER_PROCESS 16
#define WS_MAX_UDP_DATAGRAM 1024
#define WSI_BLOCKINGCALL 0x00000001 /* per-thread info flags */
#define WSI_BLOCKINGHOOK 0x00000002 /* 32-bit callback */
typedef struct _WSINFO
{
struct _WSINFO* prev,*next;
unsigned flags;
INT16 num_startup; /* reference counter */
INT16 num_async_rq;
INT16 last_free; /* entry in the socket table */
UINT16 buflen;
char* buffer; /* allocated from SEGPTR heap */
struct ws_hostent *he;
int helen;
struct ws_servent *se;
int selen;
struct ws_protoent *pe;
int pelen;
char* dbuffer; /* buffer for dummies (32 bytes) */
ws_socket sock[WS_MAX_SOCKETS_PER_PROCESS];
DWORD blocking_hook;
HTASK16 tid; /* owning task id - process might be better */
} WSINFO, *LPWSINFO;
/* function prototypes */
int WS_dup_he(LPWSINFO pwsi, struct hostent* p_he, int flag);
int WS_dup_pe(LPWSINFO pwsi, struct protoent* p_pe, int flag);
int WS_dup_se(LPWSINFO pwsi, struct servent* p_se, int flag);
BOOL WINSOCK_Init(void);
void WINSOCK_Shutdown(void);
UINT16 wsaErrno(void);
UINT16 wsaHerrno(void);
extern INT WINSOCK_DeleteTaskWSI( TDB* pTask, struct _WSINFO* );
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif /* defined(__cplusplus) */ #endif /* defined(__cplusplus) */

View File

@ -89,9 +89,6 @@ BOOL MAIN_MainInit( int *argc, char *argv[] )
/* Initialize event handling */ /* Initialize event handling */
if (!EVENT_Init()) return FALSE; if (!EVENT_Init()) return FALSE;
/* Initialise WINSOCK handling */
if (!WINSOCK_Init()) return FALSE;
/* Initialize communications */ /* Initialize communications */
COMM_Init(); COMM_Init();

View File

@ -451,11 +451,6 @@ void TASK_KillTask( HTASK16 hTask )
TRACE_(task)("Killing task %04x\n", hTask ); TRACE_(task)("Killing task %04x\n", hTask );
/* Delete active sockets */
if( pTask->pwsi )
WINSOCK_DeleteTaskWSI( pTask, pTask->pwsi );
#ifdef MZ_SUPPORTED #ifdef MZ_SUPPORTED
{ {
/* Kill DOS VM task */ /* Kill DOS VM task */

View File

@ -770,7 +770,6 @@ static void called_at_exit(void)
if (USER_Driver) if (USER_Driver)
USER_Driver->pFinalize(); USER_Driver->pFinalize();
WINSOCK_Shutdown();
CONSOLE_Close(); CONSOLE_Close();
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
name wsock32 name wsock32
type win32 type win32
init WSOCK32_LibMain
001 stdcall accept(long ptr ptr) WINSOCK_accept 001 stdcall accept(long ptr ptr) WINSOCK_accept
002 stdcall bind(long ptr long) WINSOCK_bind 002 stdcall bind(long ptr long) WINSOCK_bind

View File

@ -91,7 +91,7 @@ extern void dump_objects(void);
#define READ_EVENT 1 #define READ_EVENT 1
#define WRITE_EVENT 2 #define WRITE_EVENT 2
#define EXCEPT_EVENT 3 #define EXCEPT_EVENT 4
struct select_user struct select_user
{ {

View File

@ -84,7 +84,10 @@ static int sock_event( struct sock *sock )
static void sock_reselect( struct sock *sock ) static void sock_reselect( struct sock *sock )
{ {
set_select_events( &sock->select, sock_event( sock ) ); int ev = sock_event( sock );
if (debug_level)
fprintf(stderr,"sock_reselect(%d): new mask %x\n", sock->select.fd, ev);
set_select_events( &sock->select, ev );
} }
inline static int sock_error(int s) inline static int sock_error(int s)
@ -101,6 +104,8 @@ static void sock_select_event( int event, void *private )
struct sock *sock = (struct sock *)private; struct sock *sock = (struct sock *)private;
unsigned int emask; unsigned int emask;
assert( sock->obj.ops == &sock_ops ); assert( sock->obj.ops == &sock_ops );
if (debug_level)
fprintf(stderr, "socket %d select event: %x\n", sock->select.fd, event);
if (sock->state & WS_FD_CONNECT) if (sock->state & WS_FD_CONNECT)
{ {
/* connecting */ /* connecting */
@ -111,6 +116,8 @@ static void sock_select_event( int event, void *private )
sock->state &= ~WS_FD_CONNECT; sock->state &= ~WS_FD_CONNECT;
sock->pmask |= FD_CONNECT; sock->pmask |= FD_CONNECT;
sock->errors[FD_CONNECT_BIT] = 0; sock->errors[FD_CONNECT_BIT] = 0;
if (debug_level)
fprintf(stderr, "socket %d connection success\n", sock->select.fd);
} }
else if (event & EXCEPT_EVENT) else if (event & EXCEPT_EVENT)
{ {
@ -118,6 +125,8 @@ static void sock_select_event( int event, void *private )
sock->state &= ~WS_FD_CONNECT; sock->state &= ~WS_FD_CONNECT;
sock->pmask |= FD_CONNECT; sock->pmask |= FD_CONNECT;
sock->errors[FD_CONNECT_BIT] = sock_error( sock->select.fd ); sock->errors[FD_CONNECT_BIT] = sock_error( sock->select.fd );
if (debug_level)
fprintf(stderr, "socket %d connection failure\n", sock->select.fd);
} }
} else } else
if (sock->state & WS_FD_LISTENING) if (sock->state & WS_FD_LISTENING)
@ -151,6 +160,8 @@ static void sock_select_event( int event, void *private )
sock->pmask |= FD_READ; sock->pmask |= FD_READ;
sock->hmask |= FD_READ; sock->hmask |= FD_READ;
sock->errors[FD_READ_BIT] = 0; sock->errors[FD_READ_BIT] = 0;
if (debug_level)
fprintf(stderr, "socket %d has %d bytes\n", sock->select.fd, bytes);
} }
else else
{ {
@ -158,6 +169,8 @@ static void sock_select_event( int event, void *private )
sock->state &= ~(WS_FD_CONNECTED|WS_FD_READ|WS_FD_WRITE); sock->state &= ~(WS_FD_CONNECTED|WS_FD_READ|WS_FD_WRITE);
sock->pmask |= FD_CLOSE; sock->pmask |= FD_CLOSE;
sock->errors[FD_CLOSE_BIT] = 0; sock->errors[FD_CLOSE_BIT] = 0;
if (debug_level)
fprintf(stderr, "socket %d is closing\n", sock->select.fd);
} }
} }
if (event & WRITE_EVENT) if (event & WRITE_EVENT)
@ -165,6 +178,8 @@ static void sock_select_event( int event, void *private )
sock->pmask |= FD_WRITE; sock->pmask |= FD_WRITE;
sock->hmask |= FD_WRITE; sock->hmask |= FD_WRITE;
sock->errors[FD_WRITE_BIT] = 0; sock->errors[FD_WRITE_BIT] = 0;
if (debug_level)
fprintf(stderr, "socket %d is writable\n", sock->select.fd);
} }
if (event & EXCEPT_EVENT) if (event & EXCEPT_EVENT)
{ {
@ -174,12 +189,16 @@ static void sock_select_event( int event, void *private )
/* we got an error, socket closing? */ /* we got an error, socket closing? */
sock->state &= ~(WS_FD_CONNECTED|WS_FD_READ|WS_FD_WRITE); sock->state &= ~(WS_FD_CONNECTED|WS_FD_READ|WS_FD_WRITE);
sock->pmask |= FD_CLOSE; sock->pmask |= FD_CLOSE;
if (debug_level)
fprintf(stderr, "socket %d aborted by error %d\n", sock->select.fd, sock->errors[FD_CLOSE_BIT]);
} }
else else
{ {
/* no error, OOB data? */ /* no error, OOB data? */
sock->pmask |= FD_OOB; sock->pmask |= FD_OOB;
sock->hmask |= FD_OOB; sock->hmask |= FD_OOB;
if (debug_level)
fprintf(stderr, "socket %d got OOB data\n", sock->select.fd);
} }
} }
} }
@ -187,8 +206,12 @@ static void sock_select_event( int event, void *private )
sock_reselect( sock ); sock_reselect( sock );
/* wake up anyone waiting for whatever just happened */ /* wake up anyone waiting for whatever just happened */
emask = sock->pmask & sock->mask; emask = sock->pmask & sock->mask;
if (emask && sock->event) if (debug_level && emask)
fprintf(stderr, "socket %d pending events: %x\n", sock->select.fd, emask);
if (emask && sock->event) {
if (debug_level) fprintf(stderr, "signalling event ptr %p\n", sock->event);
set_event(sock->event); set_event(sock->event);
}
/* if anyone is stupid enough to wait on the socket object itself, /* if anyone is stupid enough to wait on the socket object itself,
* maybe we should wake them up too, just in case? */ * maybe we should wake them up too, just in case? */
@ -199,7 +222,9 @@ static void sock_dump( struct object *obj, int verbose )
{ {
struct sock *sock = (struct sock *)obj; struct sock *sock = (struct sock *)obj;
assert( obj->ops == &sock_ops ); assert( obj->ops == &sock_ops );
printf( "Socket fd=%d\n", sock->select.fd ); printf( "Socket fd=%d, state=%x, mask=%x, pending=%x, held=%x\n",
sock->select.fd, sock->state,
sock->mask, sock->pmask, sock->hmask );
} }
static int sock_add_queue( struct object *obj, struct wait_queue_entry *entry ) static int sock_add_queue( struct object *obj, struct wait_queue_entry *entry )
@ -217,7 +242,7 @@ static void sock_remove_queue( struct object *obj, struct wait_queue_entry *entr
assert( obj->ops == &sock_ops ); assert( obj->ops == &sock_ops );
remove_queue( obj, entry ); remove_queue( obj, entry );
release_object( obj ); /* release_object( obj ); */
} }
static int sock_signaled( struct object *obj, struct thread *thread ) static int sock_signaled( struct object *obj, struct thread *thread )
@ -252,11 +277,11 @@ static void sock_destroy( struct object *obj )
/* if the service thread was waiting for the event object, /* if the service thread was waiting for the event object,
* we should now signal it, to let the service thread * we should now signal it, to let the service thread
* object detect that it is now orphaned... */ * object detect that it is now orphaned... */
if (sock->mask & WS_FD_SERVEVENT)
set_event( sock->event ); set_event( sock->event );
/* we're through with it */ /* we're through with it */
release_object( sock->event ); release_object( sock->event );
} }
free( sock );
} }
/* create a new and unconnected socket */ /* create a new and unconnected socket */
@ -274,9 +299,11 @@ static struct object *create_socket( int family, int type, int protocol )
sock->hmask = 0; sock->hmask = 0;
sock->pmask = 0; sock->pmask = 0;
sock->event = NULL; sock->event = NULL;
if (debug_level)
fprintf(stderr,"socket(%d,%d,%d)=%d\n",family,type,protocol,sock->select.fd); fprintf(stderr,"socket(%d,%d,%d)=%d\n",family,type,protocol,sock->select.fd);
fcntl(sock->select.fd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */ fcntl(sock->select.fd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
register_select_user( &sock->select ); register_select_user( &sock->select );
sock_reselect( sock );
clear_error(); clear_error();
return &sock->obj; return &sock->obj;
} }
@ -313,13 +340,14 @@ static struct object *accept_socket( int handle )
acceptsock->select.fd = acceptfd; acceptsock->select.fd = acceptfd;
acceptsock->select.func = sock_select_event; acceptsock->select.func = sock_select_event;
acceptsock->select.private = sock; acceptsock->select.private = acceptsock;
acceptsock->state = WS_FD_CONNECTED|WS_FD_READ|WS_FD_WRITE; acceptsock->state = WS_FD_CONNECTED|WS_FD_READ|WS_FD_WRITE;
acceptsock->mask = sock->mask; acceptsock->mask = sock->mask;
acceptsock->hmask = 0; acceptsock->hmask = 0;
acceptsock->pmask = 0; acceptsock->pmask = 0;
acceptsock->event = (struct event *)grab_object( sock->event ); acceptsock->event = (struct event *)grab_object( sock->event );
register_select_user( &acceptsock->select ); register_select_user( &acceptsock->select );
sock_reselect( acceptsock );
clear_error(); clear_error();
sock->pmask &= ~FD_ACCEPT; sock->pmask &= ~FD_ACCEPT;
sock->hmask &= ~FD_ACCEPT; sock->hmask &= ~FD_ACCEPT;
@ -424,19 +452,22 @@ DECL_HANDLER(set_socket_event)
{ {
struct sock *sock; struct sock *sock;
struct event *oevent; struct event *oevent;
unsigned int omask;
sock=(struct sock*)get_handle_obj(current->process,req->handle,GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops); sock=(struct sock*)get_handle_obj(current->process,req->handle,GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops);
if (!sock) if (!sock)
return; return;
oevent = sock->event; oevent = sock->event;
omask = sock->mask;
sock->mask = req->mask; sock->mask = req->mask;
sock->event = get_event_obj( current->process, req->event, GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE ); sock->event = get_event_obj( current->process, req->event, EVENT_MODIFY_STATE );
if (debug_level && sock->event) fprintf(stderr, "event ptr: %p\n", sock->event);
sock_reselect( sock ); sock_reselect( sock );
if (sock->mask) if (sock->mask)
sock->state |= WS_FD_NONBLOCKING; sock->state |= WS_FD_NONBLOCKING;
if (oevent) if (oevent)
{ {
if (oevent != sock->event) if ((oevent != sock->event) && (omask & WS_FD_SERVEVENT))
/* if the service thread was waiting for the old event object, /* if the service thread was waiting for the old event object,
* we should now signal it, to let the service thread * we should now signal it, to let the service thread
* object detect that it is now orphaned... */ * object detect that it is now orphaned... */
@ -470,7 +501,7 @@ DECL_HANDLER(get_socket_event)
{ {
if (req->s_event) if (req->s_event)
{ {
struct event *sevent = get_event_obj(current->process, req->s_event, GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE); struct event *sevent = get_event_obj(current->process, req->s_event, 0);
if (sevent == sock->event) if (sevent == sock->event)
req->s_event = 0; req->s_event = 0;
release_object( sevent ); release_object( sevent );