From fd12ad12578ddc2ab313f51d0453bc823a941b57 Mon Sep 17 00:00:00 2001 From: Scott Lindeneau Date: Mon, 1 Sep 2008 05:15:58 +0900 Subject: [PATCH] Implements pop_accepting_socket To: wine-patches pop_accepting_socket pops an associated socket off of a listening socket and calls accept_socket on the listening socket using the accepting socket. It then uses async_wake_up_l to wake up the corresponding async call. When the callback is run in the dll user thread the sockets are all ready connected and accept_socket does not need to be called. This prevents race conditions. pop_accepting_socket is called instead of async_wake_up pop_accepting_socket returns true if there is an entry in the sock_list and the accept was attmpted. (even if the accept_socket fails). it returns false if there were no accepting sockets waiting. --- server/sock.c | 29 ++++++++++++++++++++++++++++- 1 files changed, 28 insertions(+), 1 deletions(-) diff --git a/server/sock.c b/server/sock.c index f481dc6..a3c9332 100644 --- a/server/sock.c +++ b/server/sock.c @@ -108,6 +108,7 @@ static void sock_queue_async_l( struct fd *fd, const async_data_t *data, int typ static void sock_reselect_async( struct fd *fd, struct async_queue *queue ); static void sock_cancel_async( struct fd *fd ); static int sock_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); +static BOOLEAN pop_accepting_socket( struct sock* listen ); static int sock_get_error( int err ); static void sock_set_error(void); @@ -258,8 +259,14 @@ static void sock_wake_up( struct sock *sock, int pollev ) int i; int async_active = 0; - if ( pollev & (POLLIN|POLLPRI) && async_waiting( sock->read_q )) + if( (pollev & POLLIN) && (sock->state & FD_WINE_LISTENING) ){ + /* this socket is listening */ + if(pop_accepting_socket(sock)) + async_active = 1; + } + if ( pollev & (POLLIN|POLLPRI) && (!(sock->state & FD_WINE_LISTENING)) && async_waiting( sock->read_q )) { + /* this socket is not listening */ if (debug_level) fprintf( stderr, "activating read queue for socket %p\n", sock ); async_wake_up( sock->read_q, STATUS_ALERTED ); async_active = 1; @@ -769,6 +776,26 @@ static struct sock *accept_socket( obj_handle_t handle, obj_handle_t ahandle ) return ret; } +/* pops an accepting socket off of a listening sockets sock_list + and accepts a connection onto the accepting socket */ +static BOOLEAN pop_accepting_socket( struct sock* listen ) +{ + struct sock_list *toPop; + struct sock *accept,*check; + struct list *ptr; + if( list_empty(&listen->slist.entry) ) + return FALSE; + ptr = list_head(&listen->slist.entry); + toPop = LIST_ENTRY(ptr,struct sock_list,entry); + accept = toPop->sock; + check = accept_socket_obj(listen,toPop->sock); + if( check != accept ) + sock_set_error(); + async_wake_up_l( listen->read_q, STATUS_ALERTED, toPop->shandle ); + list_remove(ptr); + free(toPop); + return TRUE; +} /* registers a listening socket for an accepting socket */ static void register_listening_socket( obj_handle_t lhandle, obj_handle_t ahandle ) { -- 1.5.4.3