From d1e0353beb8490bbd9b8818523c6d79daae510ff Mon Sep 17 00:00:00 2001 From: Scott Lindeneau Date: Mon, 1 Sep 2008 04:41:52 +0900 Subject: [PATCH] Implements sock_close_handle To: wine-patches Sock_close_handle needs to be implemented to correctly notify and remove any assosicated handles that were created with register_listening_socket. This is mainly a book keeping function that prevents accepting handles that are closed before making a connection from being used later by wine. 1) Clean up the async queues by removing any locatable events. 2) clean up the sock_list queue created by register_listening_socket. --- server/sock.c | 37 ++++++++++++++++++++++++++++++++++++- 1 files changed, 36 insertions(+), 1 deletions(-) diff --git a/server/sock.c b/server/sock.c index 7243bb6..f481dc6 100644 --- a/server/sock.c +++ b/server/sock.c @@ -107,6 +107,7 @@ static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, static void sock_queue_async_l( struct fd *fd, const async_data_t *data, int type, int count, obj_handle_t locator ); 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 int sock_get_error( int err ); static void sock_set_error(void); @@ -127,7 +128,7 @@ static const struct object_ops sock_ops = default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ no_open_file, /* open_file */ - fd_close_handle, /* close_handle */ + sock_close_handle, /* close_handle */ sock_destroy /* destroy */ }; @@ -561,6 +562,40 @@ static void sock_cancel_async( struct fd *fd ) async_wake_up( sock->write_q, STATUS_CANCELLED ); } +static int sock_close_handle( struct object *obj, struct process *process, obj_handle_t handle ) +{ + struct sock *sock = (struct sock*) obj; + struct sock *other = NULL; + struct list *ptr,*nxt,*optr,*onxt; + assert( sock->obj.ops == &sock_ops ); + async_wake_up( sock->read_q, STATUS_HANDLES_CLOSED ); + async_wake_up( sock->write_q, STATUS_HANDLES_CLOSED ); + if(current && sock) /*avoid fatal error when updating wine config files and testing*/ + { + LIST_FOR_EACH_SAFE(ptr,nxt, &sock->slist.entry) + { + struct sock_list *l = LIST_ENTRY(ptr,struct sock_list,entry); + other = l->sock; + async_wake_up_l( other->read_q, STATUS_HANDLES_CLOSED, handle); + async_wake_up_l( other->write_q, STATUS_HANDLES_CLOSED, handle); + LIST_FOR_EACH_SAFE(optr,onxt,&other->slist.entry) + { + struct sock_list *n = LIST_ENTRY(optr,struct sock_list,entry); + if(n->shandle == handle) /* Only delete handles matching the one closing */ + { + list_remove(optr); + free(n); /*No memory leaks please*/ + } + } + list_remove(ptr); + free(l); /*No memory leaks please*/ + } + } + + return fd_close_handle(obj,process,handle); +} + + static struct fd *sock_get_fd( struct object *obj ) { struct sock *sock = (struct sock *)obj; -- 1.5.4.3