server: Add socket-side support for the interface change notification object.
This commit is contained in:
parent
1239663fcb
commit
315de61bb2
|
@ -110,12 +110,18 @@ struct sock
|
||||||
struct sock *deferred; /* socket that waits for a deferred accept */
|
struct sock *deferred; /* socket that waits for a deferred accept */
|
||||||
struct async_queue *read_q; /* queue for asynchronous reads */
|
struct async_queue *read_q; /* queue for asynchronous reads */
|
||||||
struct async_queue *write_q; /* queue for asynchronous writes */
|
struct async_queue *write_q; /* queue for asynchronous writes */
|
||||||
|
struct async_queue *ifchange_q; /* queue for interface change notifications */
|
||||||
|
struct object *ifchange_obj; /* the interface change notification object */
|
||||||
|
struct list ifchange_entry; /* entry in ifchange notification list */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void sock_dump( struct object *obj, int verbose );
|
static void sock_dump( struct object *obj, int verbose );
|
||||||
|
static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data );
|
||||||
static int sock_signaled( struct object *obj, struct wait_queue_entry *entry );
|
static int sock_signaled( struct object *obj, struct wait_queue_entry *entry );
|
||||||
static struct fd *sock_get_fd( struct object *obj );
|
static struct fd *sock_get_fd( struct object *obj );
|
||||||
static void sock_destroy( struct object *obj );
|
static void sock_destroy( struct object *obj );
|
||||||
|
static struct async_queue *sock_get_ifchange_q( struct sock *sock );
|
||||||
|
static void sock_destroy_ifchange_q( struct sock *sock );
|
||||||
|
|
||||||
static int sock_get_poll_events( struct fd *fd );
|
static int sock_get_poll_events( struct fd *fd );
|
||||||
static void sock_poll_event( struct fd *fd, int event );
|
static void sock_poll_event( struct fd *fd, int event );
|
||||||
|
@ -534,7 +540,8 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a
|
||||||
switch(code)
|
switch(code)
|
||||||
{
|
{
|
||||||
case WS_SIO_ADDRESS_LIST_CHANGE:
|
case WS_SIO_ADDRESS_LIST_CHANGE:
|
||||||
/* intentional fallthrough, not yet supported */
|
sock_add_ifchange( sock, async_data );
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
set_error( STATUS_NOT_SUPPORTED );
|
set_error( STATUS_NOT_SUPPORTED );
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -615,6 +622,7 @@ static void sock_destroy( struct object *obj )
|
||||||
|
|
||||||
free_async_queue( sock->read_q );
|
free_async_queue( sock->read_q );
|
||||||
free_async_queue( sock->write_q );
|
free_async_queue( sock->write_q );
|
||||||
|
sock_destroy_ifchange_q( sock );
|
||||||
if (sock->event) release_object( sock->event );
|
if (sock->event) release_object( sock->event );
|
||||||
if (sock->fd)
|
if (sock->fd)
|
||||||
{
|
{
|
||||||
|
@ -642,6 +650,8 @@ static void init_sock(struct sock *sock)
|
||||||
sock->deferred = NULL;
|
sock->deferred = NULL;
|
||||||
sock->read_q = NULL;
|
sock->read_q = NULL;
|
||||||
sock->write_q = NULL;
|
sock->write_q = NULL;
|
||||||
|
sock->ifchange_q = NULL;
|
||||||
|
sock->ifchange_obj = NULL;
|
||||||
memset( sock->errors, 0, sizeof(sock->errors) );
|
memset( sock->errors, 0, sizeof(sock->errors) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -933,6 +943,81 @@ static void sock_set_error(void)
|
||||||
set_error( sock_get_ntstatus( errno ) );
|
set_error( sock_get_ntstatus( errno ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* add interface change notification to a socket */
|
||||||
|
static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data )
|
||||||
|
{
|
||||||
|
struct async_queue *ifchange_q;
|
||||||
|
struct async *async;
|
||||||
|
|
||||||
|
if (!(ifchange_q = sock_get_ifchange_q( sock )))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!(async = create_async( current, ifchange_q, async_data )))
|
||||||
|
{
|
||||||
|
if (!async_queued( ifchange_q ))
|
||||||
|
sock_destroy_ifchange_q( sock );
|
||||||
|
|
||||||
|
set_error( STATUS_NO_MEMORY );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
release_object( async );
|
||||||
|
set_error( STATUS_PENDING );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stub ifchange object */
|
||||||
|
static struct object *get_ifchange( void )
|
||||||
|
{
|
||||||
|
set_error( STATUS_NOT_SUPPORTED );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stub ifchange add socket to list */
|
||||||
|
static void ifchange_add_sock( struct object *obj, struct sock *sock )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create a new ifchange queue for a specific socket or, if one already exists, reuse the existing one */
|
||||||
|
static struct async_queue *sock_get_ifchange_q( struct sock *sock )
|
||||||
|
{
|
||||||
|
struct object *ifchange;
|
||||||
|
struct fd *fd;
|
||||||
|
|
||||||
|
if (sock->ifchange_q) /* reuse existing ifchange_q for this socket */
|
||||||
|
return sock->ifchange_q;
|
||||||
|
|
||||||
|
if (!(ifchange = get_ifchange()))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* create the ifchange notification queue */
|
||||||
|
fd = ifchange->ops->get_fd( ifchange );
|
||||||
|
sock->ifchange_q = create_async_queue( fd );
|
||||||
|
release_object( fd );
|
||||||
|
if (!sock->ifchange_q)
|
||||||
|
{
|
||||||
|
release_object( ifchange );
|
||||||
|
set_error( STATUS_NO_MEMORY );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add the socket to the ifchange notification list */
|
||||||
|
ifchange_add_sock( ifchange, sock );
|
||||||
|
sock->ifchange_obj = ifchange;
|
||||||
|
return sock->ifchange_q;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* destroy an existing ifchange queue for a specific socket */
|
||||||
|
static void sock_destroy_ifchange_q( struct sock *sock )
|
||||||
|
{
|
||||||
|
if (sock->ifchange_q)
|
||||||
|
{
|
||||||
|
list_remove( &sock->ifchange_entry );
|
||||||
|
free_async_queue( sock->ifchange_q );
|
||||||
|
sock->ifchange_q = NULL;
|
||||||
|
release_object( sock->ifchange_obj );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* create a socket */
|
/* create a socket */
|
||||||
DECL_HANDLER(create_socket)
|
DECL_HANDLER(create_socket)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue