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
116 pascal WSACleanup() WSACleanup
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 */
BYTE unused4[2]; /* 52 */
struct _TEB *teb; /* 54 Pointer to thread database */
struct _WSINFO *pwsi; /* 58 Socket control struct */
BYTE unused5[4]; /* 5B */
BYTE unused5[8]; /* 58 */
HANDLE16 hPDB; /* 60 Selector of PDB (i.e. PSP) */
SEGPTR dta WINE_PACKED; /* 62 Current DTA */
BYTE curdrive; /* 66 Current drive */

View file

@ -279,10 +279,10 @@ typedef struct WSAData {
#define WS_FD_CLOSE 0x0020
#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_RAW 0x80000000
#define WS_FD_NONBLOCKING 0x01000000
#define WS_FD_SERVEVENT 0x01000000
#define WS_FD_INTERNAL 0xFFFF0000
/*
@ -534,73 +534,6 @@ typedef struct timeval TIMEVAL, *PTIMEVAL, *LPTIMEVAL;
*/
#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
} /* extern "C" */
#endif /* defined(__cplusplus) */

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

@ -84,7 +84,10 @@ static int sock_event( 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)
@ -101,6 +104,8 @@ static void sock_select_event( int event, void *private )
struct sock *sock = (struct sock *)private;
unsigned int emask;
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)
{
/* connecting */
@ -111,6 +116,8 @@ static void sock_select_event( int event, void *private )
sock->state &= ~WS_FD_CONNECT;
sock->pmask |= FD_CONNECT;
sock->errors[FD_CONNECT_BIT] = 0;
if (debug_level)
fprintf(stderr, "socket %d connection success\n", sock->select.fd);
}
else if (event & EXCEPT_EVENT)
{
@ -118,6 +125,8 @@ static void sock_select_event( int event, void *private )
sock->state &= ~WS_FD_CONNECT;
sock->pmask |= FD_CONNECT;
sock->errors[FD_CONNECT_BIT] = sock_error( sock->select.fd );
if (debug_level)
fprintf(stderr, "socket %d connection failure\n", sock->select.fd);
}
} else
if (sock->state & WS_FD_LISTENING)
@ -151,6 +160,8 @@ static void sock_select_event( int event, void *private )
sock->pmask |= FD_READ;
sock->hmask |= FD_READ;
sock->errors[FD_READ_BIT] = 0;
if (debug_level)
fprintf(stderr, "socket %d has %d bytes\n", sock->select.fd, bytes);
}
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->pmask |= FD_CLOSE;
sock->errors[FD_CLOSE_BIT] = 0;
if (debug_level)
fprintf(stderr, "socket %d is closing\n", sock->select.fd);
}
}
if (event & WRITE_EVENT)
@ -165,6 +178,8 @@ static void sock_select_event( int event, void *private )
sock->pmask |= FD_WRITE;
sock->hmask |= FD_WRITE;
sock->errors[FD_WRITE_BIT] = 0;
if (debug_level)
fprintf(stderr, "socket %d is writable\n", sock->select.fd);
}
if (event & EXCEPT_EVENT)
{
@ -174,12 +189,16 @@ static void sock_select_event( int event, void *private )
/* we got an error, socket closing? */
sock->state &= ~(WS_FD_CONNECTED|WS_FD_READ|WS_FD_WRITE);
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
{
/* no error, OOB data? */
sock->pmask |= 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 );
/* wake up anyone waiting for whatever just happened */
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);
}
/* if anyone is stupid enough to wait on the socket object itself,
* 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;
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 )
@ -217,7 +242,7 @@ static void sock_remove_queue( struct object *obj, struct wait_queue_entry *entr
assert( obj->ops == &sock_ops );
remove_queue( obj, entry );
release_object( obj );
/* release_object( obj ); */
}
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,
* we should now signal it, to let the service thread
* object detect that it is now orphaned... */
set_event( sock->event );
if (sock->mask & WS_FD_SERVEVENT)
set_event( sock->event );
/* we're through with it */
release_object( sock->event );
}
free( sock );
}
/* 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->pmask = 0;
sock->event = NULL;
fprintf(stderr,"socket(%d,%d,%d)=%d\n",family,type,protocol,sock->select.fd);
if (debug_level)
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 */
register_select_user( &sock->select );
sock_reselect( sock );
clear_error();
return &sock->obj;
}
@ -313,13 +340,14 @@ static struct object *accept_socket( int handle )
acceptsock->select.fd = acceptfd;
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->mask = sock->mask;
acceptsock->hmask = 0;
acceptsock->pmask = 0;
acceptsock->event = (struct event *)grab_object( sock->event );
register_select_user( &acceptsock->select );
sock_reselect( acceptsock );
clear_error();
sock->pmask &= ~FD_ACCEPT;
sock->hmask &= ~FD_ACCEPT;
@ -424,19 +452,22 @@ DECL_HANDLER(set_socket_event)
{
struct sock *sock;
struct event *oevent;
unsigned int omask;
sock=(struct sock*)get_handle_obj(current->process,req->handle,GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops);
if (!sock)
return;
oevent = sock->event;
omask = sock->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 );
if (sock->mask)
sock->state |= WS_FD_NONBLOCKING;
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,
* we should now signal it, to let the service thread
* object detect that it is now orphaned... */
@ -470,7 +501,7 @@ DECL_HANDLER(get_socket_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)
req->s_event = 0;
release_object( sevent );