From ac0785995cc6c4c483c3097646b8baf80c8b6e0b Mon Sep 17 00:00:00 2001 From: Scott Lindeneau Date: Fri, 22 Aug 2008 02:10:49 +0900 Subject: [PATCH] Implements a nuber of socket functions required by AcceptEx To: wine-patches sock.c: add's a listen handler to identify a socket that is listening for connections that will be accepted onto this socket. This allows the accepting socket to notify the listening socket when it is no longer ready to accept connections.(AcceptEx Requires this.) sock.c: impelements new DECL_HANDLER set_socket_listener to set the above listen handler.(AcceptEx Requires this.) sock.c: Implements sock_close_handle to correctly close all associated async requests.(AcceptEx Requires this.) fd.c: Implements new DECL_HANDLER register_async_l to register a locatable async event. protocol.def: Assosciated changes for above to work. Otherfiles changed by tools/make_requests --- include/wine/server_protocol.h | 34 +++++++++- server/fd.c | 28 ++++++++ server/file.h | 7 ++ server/protocol.def | 14 ++++ server/request.h | 4 + server/sock.c | 142 ++++++++++++++++++++++++++++++---------- server/trace.c | 23 +++++++ 7 files changed, 217 insertions(+), 35 deletions(-) diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 7b6e631..eb9f433 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -1154,6 +1154,7 @@ struct accept_socket_request { struct request_header __header; obj_handle_t lhandle; + obj_handle_t ahandle; unsigned int access; unsigned int attributes; }; @@ -1180,6 +1181,17 @@ struct set_socket_event_reply }; +struct set_socket_listener_request +{ + struct request_header __header; + obj_handle_t handle; + obj_handle_t hListen; +}; +struct set_socket_listener_reply +{ + struct reply_header __header; +}; + struct get_socket_event_request { @@ -2661,6 +2673,20 @@ struct register_async_reply { struct reply_header __header; }; + +struct register_async_l_request +{ + struct request_header __header; + obj_handle_t handle; + int type; + int count; + obj_handle_t locator; + async_data_t async; +}; +struct register_async_l_reply +{ + struct reply_header __header; +}; #define ASYNC_TYPE_READ 0x01 #define ASYNC_TYPE_WRITE 0x02 #define ASYNC_TYPE_WAIT 0x03 @@ -4313,6 +4339,7 @@ enum request REQ_create_socket, REQ_accept_socket, REQ_set_socket_event, + REQ_set_socket_listener, REQ_get_socket_event, REQ_enable_socket_event, REQ_set_socket_deferred, @@ -4402,6 +4429,7 @@ enum request REQ_get_serial_info, REQ_set_serial_info, REQ_register_async, + REQ_register_async_l, REQ_cancel_async, REQ_ioctl, REQ_get_ioctl_result, @@ -4552,6 +4580,7 @@ union generic_request struct create_socket_request create_socket_request; struct accept_socket_request accept_socket_request; struct set_socket_event_request set_socket_event_request; + struct set_socket_listener_request set_socket_listener_request; struct get_socket_event_request get_socket_event_request; struct enable_socket_event_request enable_socket_event_request; struct set_socket_deferred_request set_socket_deferred_request; @@ -4641,6 +4670,7 @@ union generic_request struct get_serial_info_request get_serial_info_request; struct set_serial_info_request set_serial_info_request; struct register_async_request register_async_request; + struct register_async_l_request register_async_l_request; struct cancel_async_request cancel_async_request; struct ioctl_request ioctl_request; struct get_ioctl_result_request get_ioctl_result_request; @@ -4789,6 +4819,7 @@ union generic_reply struct create_socket_reply create_socket_reply; struct accept_socket_reply accept_socket_reply; struct set_socket_event_reply set_socket_event_reply; + struct set_socket_listener_reply set_socket_listener_reply; struct get_socket_event_reply get_socket_event_reply; struct enable_socket_event_reply enable_socket_event_reply; struct set_socket_deferred_reply set_socket_deferred_reply; @@ -4878,6 +4909,7 @@ union generic_reply struct get_serial_info_reply get_serial_info_reply; struct set_serial_info_reply set_serial_info_reply; struct register_async_reply register_async_reply; + struct register_async_l_reply register_async_l_reply; struct cancel_async_reply cancel_async_reply; struct ioctl_reply ioctl_reply; struct get_ioctl_result_reply get_ioctl_result_reply; @@ -4979,6 +5011,6 @@ union generic_reply struct add_fd_completion_reply add_fd_completion_reply; }; -#define SERVER_PROTOCOL_VERSION 341 +#define SERVER_PROTOCOL_VERSION 343 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/fd.c b/server/fd.c index 0d33e77..93dfe78 100644 --- a/server/fd.c +++ b/server/fd.c @@ -1857,6 +1857,7 @@ void default_fd_cancel_async( struct fd *fd ) async_wake_up( fd->wait_q, STATUS_CANCELLED ); } + /* default flush() routine */ void no_flush( struct fd *fd, struct event **event ) { @@ -2048,6 +2049,32 @@ DECL_HANDLER(register_async) } } +/* create / reschedule an async I/O */ +DECL_HANDLER(register_async_l) +{ + unsigned int access; + struct fd *fd; + + switch(req->type) + { + case ASYNC_TYPE_READ: + access = FILE_READ_DATA; + break; + case ASYNC_TYPE_WRITE: + access = FILE_WRITE_DATA; + break; + default: + set_error( STATUS_INVALID_PARAMETER ); + return; + } + + if ((fd = get_handle_fd_obj( current->process, req->handle, access ))) + { + if (get_unix_fd( fd ) != -1) fd->fd_ops->queue_async_l( fd, &req->async, req->type, req->count, req->locator ); + release_object( fd ); + } +} + /* cancels all async I/O */ DECL_HANDLER(cancel_async) { @@ -2060,6 +2087,7 @@ DECL_HANDLER(cancel_async) } } + /* attach completion object to a fd */ DECL_HANDLER(set_completion_info) { diff --git a/server/file.h b/server/file.h index 26d1702..ef83a0c 100644 --- a/server/file.h +++ b/server/file.h @@ -47,6 +47,9 @@ struct fd_ops void (*reselect_async)( struct fd *, struct async_queue *queue ); /* cancel an async operation */ void (*cancel_async)(struct fd *); + /* queue a locatable async operation */ + void (*queue_async_l)(struct fd *, const async_data_t *data, int type, int count, obj_handle_t locator); + }; /* file descriptor functions */ @@ -134,11 +137,15 @@ extern struct async_queue *create_async_queue( struct fd *fd ); extern void free_async_queue( struct async_queue *queue ); extern struct async *create_async( struct thread *thread, struct async_queue *queue, const async_data_t *data ); +extern struct async *create_async_l( struct thread *thread, struct async_queue *queue, + const async_data_t *data, obj_handle_t l ); + extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status ); extern void async_set_result( struct object *obj, unsigned int status, unsigned long total ); extern int async_waiting( struct async_queue *queue ); extern void async_terminate( struct async *async, unsigned int status ); extern void async_wake_up( struct async_queue *queue, unsigned int status ); +extern void async_wake_up_l( struct async_queue *queue, unsigned int status, obj_handle_t l ); extern void fd_assign_completion( struct fd *fd, struct completion **p_port, unsigned long *p_key ); /* access rights that require Unix read permission */ diff --git a/server/protocol.def b/server/protocol.def index db2d171..28f27ee 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -950,6 +950,7 @@ enum server_fd_type /* Accept a socket */ @REQ(accept_socket) obj_handle_t lhandle; /* handle to the listening socket */ + obj_handle_t ahandle; /* handle to the accepting socket */ unsigned int access; /* wanted access rights */ unsigned int attributes; /* object attributes */ @REPLY @@ -966,6 +967,11 @@ enum server_fd_type unsigned int msg; /* message to send */ @END +/* Set socket listener */ +@REQ(set_socket_listener) + obj_handle_t handle; /* handle to the socket */ + obj_handle_t hListen; /* handle to the socket listening for connections */ +@END /* Get socket event parameters */ @REQ(get_socket_event) @@ -1968,6 +1974,14 @@ enum message_type int count; /* count - usually # of bytes to be read/written */ async_data_t async; /* async I/O parameters */ @END +/* Create a locatable async I/O */ +@REQ(register_async_l) + obj_handle_t handle; /* handle to comm port, socket or file */ + int type; /* type of queue to look after */ + int count; /* count - usually # of bytes to be read/written */ + obj_handle_t locator; /* used to locate a specific async request later */ + async_data_t async; /* async I/O parameters */ +@END #define ASYNC_TYPE_READ 0x01 #define ASYNC_TYPE_WRITE 0x02 #define ASYNC_TYPE_WAIT 0x03 diff --git a/server/request.h b/server/request.h index 14d3246..ee253f4 100644 --- a/server/request.h +++ b/server/request.h @@ -155,6 +155,7 @@ DECL_HANDLER(unlock_file); DECL_HANDLER(create_socket); DECL_HANDLER(accept_socket); DECL_HANDLER(set_socket_event); +DECL_HANDLER(set_socket_listener); DECL_HANDLER(get_socket_event); DECL_HANDLER(enable_socket_event); DECL_HANDLER(set_socket_deferred); @@ -244,6 +245,7 @@ DECL_HANDLER(is_window_hung); DECL_HANDLER(get_serial_info); DECL_HANDLER(set_serial_info); DECL_HANDLER(register_async); +DECL_HANDLER(register_async_l); DECL_HANDLER(cancel_async); DECL_HANDLER(ioctl); DECL_HANDLER(get_ioctl_result); @@ -393,6 +395,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_create_socket, (req_handler)req_accept_socket, (req_handler)req_set_socket_event, + (req_handler)req_set_socket_listener, (req_handler)req_get_socket_event, (req_handler)req_enable_socket_event, (req_handler)req_set_socket_deferred, @@ -482,6 +485,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_get_serial_info, (req_handler)req_set_serial_info, (req_handler)req_register_async, + (req_handler)req_register_async_l, (req_handler)req_cancel_async, (req_handler)req_ioctl, (req_handler)req_get_ioctl_result, diff --git a/server/sock.c b/server/sock.c index f4fe25e..58a1d35 100644 --- a/server/sock.c +++ b/server/sock.c @@ -85,6 +85,7 @@ struct sock struct sock *deferred; /* socket that waits for a deferred accept */ struct async_queue *read_q; /* queue for asynchronous reads */ struct async_queue *write_q; /* queue for asynchronous writes */ + obj_handle_t *hListen; /* socket listening for connections for this one */ }; static void sock_dump( struct object *obj, int verbose ); @@ -96,8 +97,12 @@ static int sock_get_poll_events( struct fd *fd ); static void sock_poll_event( struct fd *fd, int event ); static enum server_fd_type sock_get_fd_type( struct fd *fd ); static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); +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 void sock_async_close_l( struct sock *sock, obj_handle_t locator ); + static int sock_get_error( int err ); static void sock_set_error(void); @@ -118,7 +123,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 */ }; @@ -131,7 +136,8 @@ static const struct fd_ops sock_fd_ops = default_fd_ioctl, /* ioctl */ sock_queue_async, /* queue_async */ sock_reselect_async, /* reselect_async */ - sock_cancel_async /* cancel_async */ + sock_cancel_async, /* cancel_async */ + sock_queue_async_l /* quque_async_l */ }; @@ -247,7 +253,6 @@ static void sock_wake_up( struct sock *sock, int pollev ) unsigned int events = sock->pmask & sock->mask; int i; int async_active = 0; - if ( pollev & (POLLIN|POLLPRI) && async_waiting( sock->read_q )) { if (debug_level) fprintf( stderr, "activating read queue for socket %p\n", sock ); @@ -332,6 +337,7 @@ static void sock_poll_event( struct fd *fd, int event ) /* listening */ if (event & POLLIN) { + /* incoming connection */ sock->pmask |= FD_ACCEPT; sock->errors[FD_ACCEPT_BIT] = 0; @@ -435,10 +441,12 @@ static void sock_poll_event( struct fd *fd, int event ) } else sock_reselect( sock ); - + /* wake up anyone waiting for whatever just happened */ - if ( sock->pmask & sock->mask || sock->flags & WSA_FLAG_OVERLAPPED ) sock_wake_up( sock, event ); - + if ( sock->pmask & sock->mask || sock->flags & WSA_FLAG_OVERLAPPED ) + { + sock_wake_up( sock, event ); + } /* if anyone is stupid enough to wait on the socket object itself, * maybe we should wake them up too, just in case? */ wake_up( &sock->obj, 0 ); @@ -466,7 +474,7 @@ static int sock_get_poll_events( struct fd *fd ) struct sock *sock = get_fd_user( fd ); unsigned int mask = sock->mask & sock->state & ~sock->hmask; int ev = 0; - + assert( sock->obj.ops == &sock_ops ); if (sock->state & FD_CONNECT) @@ -490,7 +498,7 @@ static enum server_fd_type sock_get_fd_type( struct fd *fd ) return FD_TYPE_SOCKET; } -static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count ) +static void sock_queue_async_l( struct fd *fd, const async_data_t *data, int type, int count, obj_handle_t locator ) { struct sock *sock = get_fd_user( fd ); struct async_queue *queue; @@ -514,7 +522,7 @@ static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, return; } - if ( ( !( sock->state & FD_READ ) && type == ASYNC_TYPE_READ ) || + if ( ( !( sock->state & (FD_READ|FD_WINE_LISTENING) ) && type == ASYNC_TYPE_READ ) || ( !( sock->state & FD_WRITE ) && type == ASYNC_TYPE_WRITE ) ) { set_error( STATUS_PIPE_DISCONNECTED ); @@ -522,7 +530,7 @@ static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, else { struct async *async; - if (!(async = create_async( current, queue, data ))) return; + if (!(async = create_async_l( current, queue, data, locator ))) return; release_object( async ); set_error( STATUS_PENDING ); } @@ -530,6 +538,10 @@ static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, pollev = sock_reselect( sock ); if ( pollev ) sock_try_event( sock, pollev ); } +static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count) +{ + sock_queue_async_l(fd,data,type,count,NULL); +} static void sock_reselect_async( struct fd *fd, struct async_queue *queue ) { @@ -542,11 +554,38 @@ static void sock_cancel_async( struct fd *fd ) { struct sock *sock = get_fd_user( fd ); assert( sock->obj.ops == &sock_ops ); - async_wake_up( sock->read_q, STATUS_CANCELLED ); 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 *l = NULL; + 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*/ + l = (struct sock *)get_handle_obj( process, sock->hListen, FILE_WRITE_ATTRIBUTES, &sock_ops ); + if(l) + { + sock_async_close_l( l, handle ); + release_object( l ); + }else{ + clear_error(); + } + } + + return fd_close_handle(obj,process,handle); +} + +/*Closes all async operations on a socket with the corresponding locator */ +static void sock_async_close_l( struct sock *sock, obj_handle_t locator ) +{ + async_wake_up_l( sock->read_q, STATUS_HANDLES_CLOSED, locator ); + async_wake_up_l( sock->write_q, STATUS_HANDLES_CLOSED, locator ); +} + static struct fd *sock_get_fd( struct object *obj ) { struct sock *sock = (struct sock *)obj; @@ -621,16 +660,17 @@ static struct object *create_socket( int family, int type, int protocol, unsigne } /* accept a socket (creates a new fd) */ -static struct sock *accept_socket( obj_handle_t handle ) +static struct sock *accept_socket( obj_handle_t handle, obj_handle_t ahandle ) { - struct sock *acceptsock; + struct sock *acceptsock = NULL; struct sock *sock; - int acceptfd; - struct sockaddr saddr; - + int acceptfd; + struct sockaddr saddr; + sock = (struct sock *)get_handle_obj( current->process, handle, FILE_READ_DATA, &sock_ops ); - if (!sock) - return NULL; + if (!sock){ + return NULL; + } if ( sock->deferred ) { @@ -652,37 +692,49 @@ static struct sock *accept_socket( obj_handle_t handle ) release_object( sock ); return NULL; } - if (!(acceptsock = alloc_object( &sock_ops ))) + + if(ahandle){ + acceptsock = (struct sock *)get_handle_obj(current->process, ahandle, FILE_READ_DATA | FILE_WRITE_DATA, &sock_ops ); + if(acceptsock){ + if(acceptsock->event) + release_object( acceptsock->event ); + release_object( acceptsock->fd ); + } + }else{ + acceptsock = alloc_object( &sock_ops ); + } + if (!acceptsock) { close( acceptfd ); release_object( sock ); return NULL; } + - /* newly created socket gets the same properties of the listening socket */ fcntl(acceptfd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */ acceptsock->state = FD_WINE_CONNECTED|FD_READ|FD_WRITE; - if (sock->state & FD_WINE_NONBLOCKING) - acceptsock->state |= FD_WINE_NONBLOCKING; - acceptsock->mask = sock->mask; acceptsock->hmask = 0; acceptsock->pmask = 0; acceptsock->polling = 0; + acceptsock->event = NULL; + acceptsock->deferred = NULL; + acceptsock->read_q = NULL; + acceptsock->write_q = NULL; + acceptsock->wparam = 0; + /* newly created socket gets the same properties of the listening socket */ + if (sock->state & FD_WINE_NONBLOCKING) + acceptsock->state |= FD_WINE_NONBLOCKING; + acceptsock->mask = sock->mask; acceptsock->type = sock->type; acceptsock->family = sock->family; - acceptsock->event = NULL; acceptsock->window = sock->window; acceptsock->message = sock->message; - acceptsock->wparam = 0; if (sock->event) acceptsock->event = (struct event *)grab_object( sock->event ); acceptsock->flags = sock->flags; - acceptsock->deferred = NULL; - acceptsock->read_q = NULL; - acceptsock->write_q = NULL; if (!(acceptsock->fd = create_anonymous_fd( &sock_fd_ops, acceptfd, &acceptsock->obj, get_fd_options( sock->fd ) ))) { - release_object( acceptsock ); + release_object( acceptsock ); release_object( sock ); return NULL; } @@ -787,15 +839,37 @@ DECL_HANDLER(accept_socket) struct sock *sock; reply->handle = 0; - if ((sock = accept_socket( req->lhandle )) != NULL) + if ((sock = accept_socket( req->lhandle, req->ahandle )) != NULL) { - reply->handle = alloc_handle( current->process, &sock->obj, req->access, req->attributes ); - sock->wparam = reply->handle; /* wparam for message is the socket handle */ - sock_reselect( sock ); - release_object( &sock->obj ); + if (req->ahandle) + reply->handle = req->ahandle; + else + { + reply->handle = alloc_handle( current->process, &sock->obj, req->access, req->attributes ); + sock->wparam = reply->handle; /* wparam for message is the socket handle */ + sock_reselect( sock ); + } + release_object( &sock->obj );//I think this needs togo in the else. But i want to check. + //We can't release the object unless we allocate a handle for it. + //Do we need to se the wparam? What is this? No... maybe... i dont know. } } +/* Sets which socket is listening for connections for this socket */ +DECL_HANDLER(set_socket_listener) +{ + struct sock *sock; + sock = (struct sock *)get_handle_obj( current->process, req->handle, FILE_WRITE_ATTRIBUTES, &sock_ops ); + if(!sock){ + set_error( STATUS_INVALID_HANDLE ); + return; + } + sock->hListen = req->hListen; + release_object( &sock->obj ); + set_error( STATUS_SUCCESS ); + return; +} + /* set socket event parameters */ DECL_HANDLER(set_socket_event) { diff --git a/server/trace.c b/server/trace.c index 70cb13b..35854c1 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1398,6 +1398,7 @@ static void dump_create_socket_reply( const struct create_socket_reply *req ) static void dump_accept_socket_request( const struct accept_socket_request *req ) { fprintf( stderr, " lhandle=%p,", req->lhandle ); + fprintf( stderr, " ahandle=%p,", req->ahandle ); fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " attributes=%08x", req->attributes ); } @@ -1416,6 +1417,12 @@ static void dump_set_socket_event_request( const struct set_socket_event_request fprintf( stderr, " msg=%08x", req->msg ); } +static void dump_set_socket_listener_request( const struct set_socket_listener_request *req ) +{ + fprintf( stderr, " handle=%p,", req->handle ); + fprintf( stderr, " hListen=%p", req->hListen ); +} + static void dump_get_socket_event_request( const struct get_socket_event_request *req ) { fprintf( stderr, " handle=%p,", req->handle ); @@ -2470,6 +2477,16 @@ static void dump_register_async_request( const struct register_async_request *re dump_async_data( &req->async ); } +static void dump_register_async_l_request( const struct register_async_l_request *req ) +{ + fprintf( stderr, " handle=%p,", req->handle ); + fprintf( stderr, " type=%d,", req->type ); + fprintf( stderr, " count=%d,", req->count ); + fprintf( stderr, " locator=%p,", req->locator ); + fprintf( stderr, " async=" ); + dump_async_data( &req->async ); +} + static void dump_cancel_async_request( const struct cancel_async_request *req ) { fprintf( stderr, " handle=%p", req->handle ); @@ -3818,6 +3835,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_create_socket_request, (dump_func)dump_accept_socket_request, (dump_func)dump_set_socket_event_request, + (dump_func)dump_set_socket_listener_request, (dump_func)dump_get_socket_event_request, (dump_func)dump_enable_socket_event_request, (dump_func)dump_set_socket_deferred_request, @@ -3907,6 +3925,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_get_serial_info_request, (dump_func)dump_set_serial_info_request, (dump_func)dump_register_async_request, + (dump_func)dump_register_async_l_request, (dump_func)dump_cancel_async_request, (dump_func)dump_ioctl_request, (dump_func)dump_get_ioctl_result_request, @@ -4053,6 +4072,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_create_socket_reply, (dump_func)dump_accept_socket_reply, (dump_func)0, + (dump_func)0, (dump_func)dump_get_socket_event_reply, (dump_func)0, (dump_func)0, @@ -4143,6 +4163,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)0, (dump_func)0, (dump_func)0, + (dump_func)0, (dump_func)dump_ioctl_reply, (dump_func)dump_get_ioctl_result_reply, (dump_func)dump_create_named_pipe_reply, @@ -4288,6 +4309,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "create_socket", "accept_socket", "set_socket_event", + "set_socket_listener", "get_socket_event", "enable_socket_event", "set_socket_deferred", @@ -4377,6 +4399,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "get_serial_info", "set_serial_info", "register_async", + "register_async_l", "cancel_async", "ioctl", "get_ioctl_result", -- 1.5.4.3