Signed-off-by: Zebediah Figura z.figura12@gmail.com --- server/protocol.def | 1 - server/sock.c | 1 - 2 files changed, 2 deletions(-)
diff --git a/server/protocol.def b/server/protocol.def index 30624a7cbaf..3609261b848 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1441,7 +1441,6 @@ enum server_fd_type @REPLY unsigned int mask; /* event mask */ unsigned int pmask; /* pending events */ - unsigned int state; /* status bits */ VARARG(errors,ints); /* event errors */ @END
diff --git a/server/sock.c b/server/sock.c index b4649abbf08..bbd82d57bd5 100644 --- a/server/sock.c +++ b/server/sock.c @@ -2376,7 +2376,6 @@ DECL_HANDLER(get_socket_event) if (get_unix_fd( sock->fd ) == -1) return; reply->mask = sock->mask; reply->pmask = sock->pending_events; - reply->state = sock->state; set_reply_data( sock->errors, min( get_reply_max_size(), sizeof(sock->errors) ));
if (req->service)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- include/winsock2.h | 1 - server/sock.c | 29 +++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/include/winsock2.h b/include/winsock2.h index c299583eaff..a10f81db668 100644 --- a/include/winsock2.h +++ b/include/winsock2.h @@ -293,7 +293,6 @@ extern "C" {
#ifdef __WINESRC__ #define FD_WINE_LISTENING 0x10000000 -#define FD_WINE_NONBLOCKING 0x20000000 #define FD_WINE_CONNECTED 0x40000000 #endif
diff --git a/server/sock.c b/server/sock.c index bbd82d57bd5..7941ed856d3 100644 --- a/server/sock.c +++ b/server/sock.c @@ -151,7 +151,6 @@ struct sock * any event once until it is reset.) */ unsigned int reported_events; unsigned int flags; /* socket flags */ - int wr_shutdown_pending; /* is a write shutdown pending? */ unsigned short proto; /* socket protocol */ unsigned short type; /* socket type */ unsigned short family; /* socket family */ @@ -173,6 +172,8 @@ struct sock struct list accept_list; /* list of pending accept requests */ struct accept_req *accept_recv_req; /* pending accept-into request which will recv on this socket */ struct connect_req *connect_req; /* pending connection request */ + unsigned int wr_shutdown_pending : 1; /* is a write shutdown pending? */ + unsigned int nonblocking : 1; /* is the socket nonblocking? */ };
static void sock_dump( struct object *obj, int verbose ); @@ -1166,7 +1167,6 @@ static struct sock *create_socket(void) sock->mask = 0; sock->pending_events = 0; sock->reported_events = 0; - sock->wr_shutdown_pending = 0; sock->flags = 0; sock->proto = 0; sock->type = 0; @@ -1180,6 +1180,8 @@ static struct sock *create_socket(void) sock->ifchange_obj = NULL; sock->accept_recv_req = NULL; sock->connect_req = NULL; + sock->wr_shutdown_pending = 0; + sock->nonblocking = 0; init_async_queue( &sock->read_q ); init_async_queue( &sock->write_q ); init_async_queue( &sock->ifchange_q ); @@ -1403,8 +1405,7 @@ static struct sock *accept_socket( struct sock *sock )
/* newly created socket gets the same properties of the listening socket */ acceptsock->state = FD_WINE_CONNECTED|FD_READ|FD_WRITE; - if (sock->state & FD_WINE_NONBLOCKING) - acceptsock->state |= FD_WINE_NONBLOCKING; + acceptsock->nonblocking = sock->nonblocking; acceptsock->mask = sock->mask; acceptsock->proto = sock->proto; acceptsock->type = sock->type; @@ -1657,7 +1658,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) { struct accept_req *req;
- if (sock->state & FD_WINE_NONBLOCKING) return 0; + if (sock->nonblocking) return 0; if (get_error() != STATUS_DEVICE_NOT_READY) return 0;
if (!(req = alloc_accept_req( sock, NULL, async, NULL ))) return 0; @@ -1818,7 +1819,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
sock->state |= FD_CONNECT;
- if (params->synchronous && (sock->state & FD_WINE_NONBLOCKING)) + if (params->synchronous && sock->nonblocking) { sock_reselect( sock ); set_error( STATUS_DEVICE_NOT_READY ); @@ -1882,7 +1883,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) sock->event = NULL; sock->window = 0; sock->mask = 0; - sock->state |= FD_WINE_NONBLOCKING; + sock->nonblocking = 1; }
sock_reselect( sock ); @@ -1900,7 +1901,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) } force_async = *(int *)get_req_data();
- if ((sock->state & FD_WINE_NONBLOCKING) && !force_async) + if (sock->nonblocking && !force_async) { set_error( STATUS_DEVICE_NOT_READY ); return 0; @@ -1919,7 +1920,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) } if (*(int *)get_req_data()) { - sock->state |= FD_WINE_NONBLOCKING; + sock->nonblocking = 1; } else { @@ -1928,7 +1929,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) set_error( STATUS_INVALID_PARAMETER ); return 0; } - sock->state &= ~FD_WINE_NONBLOCKING; + sock->nonblocking = 0; } return 1;
@@ -2354,7 +2355,7 @@ DECL_HANDLER(set_socket_event)
sock_reselect( sock );
- sock->state |= FD_WINE_NONBLOCKING; + sock->nonblocking = 1;
/* if a network event is pending, signal the event object it is possible that FD_CONNECT or FD_ACCEPT network events has happened @@ -2442,7 +2443,7 @@ DECL_HANDLER(recv_socket) fd = sock->fd;
/* recv() returned EWOULDBLOCK, i.e. no data available yet */ - if (status == STATUS_DEVICE_NOT_READY && !(sock->state & FD_WINE_NONBLOCKING)) + if (status == STATUS_DEVICE_NOT_READY && !sock->nonblocking) { #ifdef SO_RCVTIMEO struct timeval tv; @@ -2543,11 +2544,11 @@ DECL_HANDLER(send_socket) * not trying to force the operation to be asynchronous), return success. * Windows actually refuses to send any data in this case, and returns * EWOULDBLOCK, but we have no way of doing that. */ - if (status == STATUS_DEVICE_NOT_READY && req->total && (sock->state & FD_WINE_NONBLOCKING)) + if (status == STATUS_DEVICE_NOT_READY && req->total && sock->nonblocking) status = STATUS_SUCCESS;
/* send() returned EWOULDBLOCK or a short write, i.e. cannot send all data yet */ - if (status == STATUS_DEVICE_NOT_READY && !(sock->state & FD_WINE_NONBLOCKING)) + if (status == STATUS_DEVICE_NOT_READY && !sock->nonblocking) { #ifdef SO_SNDTIMEO struct timeval tv;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- server/sock.c | 59 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 21 deletions(-)
diff --git a/server/sock.c b/server/sock.c index 7941ed856d3..4cd84637baf 100644 --- a/server/sock.c +++ b/server/sock.c @@ -172,6 +172,8 @@ struct sock struct list accept_list; /* list of pending accept requests */ struct accept_req *accept_recv_req; /* pending accept-into request which will recv on this socket */ struct connect_req *connect_req; /* pending connection request */ + unsigned int rd_shutdown : 1; /* is the read end shut down? */ + unsigned int wr_shutdown : 1; /* is the write end shut down? */ unsigned int wr_shutdown_pending : 1; /* is a write shutdown pending? */ unsigned int nonblocking : 1; /* is the socket nonblocking? */ }; @@ -781,9 +783,9 @@ static int sock_dispatch_asyncs( struct sock *sock, int event, int error ) int status = sock_get_ntstatus( error ); struct accept_req *req, *next;
- if (!(sock->state & FD_READ)) + if (sock->rd_shutdown) async_wake_up( &sock->read_q, status ); - if (!(sock->state & FD_WRITE)) + if (sock->wr_shutdown) async_wake_up( &sock->write_q, status );
LIST_FOR_EACH_ENTRY_SAFE( req, next, &sock->accept_list, struct accept_req, entry ) @@ -869,7 +871,7 @@ static void sock_poll_event( struct fd *fd, int event ) else if (event & POLLOUT) { /* we got connected */ - sock->state |= FD_WINE_CONNECTED|FD_READ|FD_WRITE; + sock->state |= FD_WINE_CONNECTED; sock->state &= ~FD_CONNECT; sock->connect_time = current_time; } @@ -911,12 +913,12 @@ static void sock_poll_event( struct fd *fd, int event ) } }
- if ( (hangup_seen || event & (POLLHUP|POLLERR)) && (sock->state & (FD_READ|FD_WRITE)) ) + if ((hangup_seen || event & (POLLHUP | POLLERR)) && (!sock->rd_shutdown || !sock->wr_shutdown)) { error = error ? error : sock_error( fd ); if ( (event & POLLERR) || ( sock_shutdown_type == SOCK_SHUTDOWN_EOF && (event & POLLHUP) )) - sock->state &= ~FD_WRITE; - sock->state &= ~FD_READ; + sock->wr_shutdown = 1; + sock->rd_shutdown = 1;
if (debug_level) fprintf(stderr, "socket %p aborted by error %d, event: %x\n", sock, error, event); @@ -969,7 +971,6 @@ static int sock_get_poll_events( struct fd *fd ) { struct sock *sock = get_fd_user( fd ); unsigned int mask = sock->mask & ~sock->reported_events; - unsigned int smask = sock->state & mask; struct poll_req *req; int ev = 0;
@@ -996,7 +997,12 @@ static int sock_get_poll_events( struct fd *fd ) { if (async_waiting( &sock->read_q )) ev |= POLLIN | POLLPRI; } - else if (smask & FD_READ || (sock->state & FD_WINE_LISTENING && mask & FD_ACCEPT)) + else if (sock->state & FD_WINE_LISTENING) + { + if (mask & FD_ACCEPT) + ev |= POLLIN; + } + else if (!sock->rd_shutdown && (mask & FD_READ)) ev |= POLLIN | POLLPRI; /* We use POLLIN with 0 bytes recv() as FD_CLOSE indication for stream sockets. */ else if (sock->type == WS_SOCK_STREAM && (mask & FD_CLOSE) && !(sock->reported_events & FD_READ)) @@ -1006,7 +1012,7 @@ static int sock_get_poll_events( struct fd *fd ) { if (async_waiting( &sock->write_q )) ev |= POLLOUT; } - else if (smask & FD_WRITE) + else if (!sock->wr_shutdown && (mask & FD_WRITE)) ev |= POLLOUT;
LIST_FOR_EACH_ENTRY( req, &poll_list, struct poll_req, entry ) @@ -1039,18 +1045,30 @@ static void sock_queue_async( struct fd *fd, struct async *async, int type, int switch (type) { case ASYNC_TYPE_READ: + if (sock->rd_shutdown) + { + set_error( STATUS_PIPE_DISCONNECTED ); + return; + } queue = &sock->read_q; break; + case ASYNC_TYPE_WRITE: + if (sock->wr_shutdown) + { + set_error( STATUS_PIPE_DISCONNECTED ); + return; + } queue = &sock->write_q; break; + default: set_error( STATUS_INVALID_PARAMETER ); return; }
- if ( ( !( sock->state & (FD_READ|FD_CONNECT|FD_WINE_LISTENING) ) && type == ASYNC_TYPE_READ ) || - ( !( sock->state & (FD_WRITE|FD_CONNECT) ) && type == ASYNC_TYPE_WRITE ) ) + if ( ( !( sock->state & (FD_CONNECT|FD_WINE_LISTENING) ) && type == ASYNC_TYPE_READ ) || + ( !( sock->state & (FD_CONNECT) ) && type == ASYNC_TYPE_WRITE ) ) { set_error( STATUS_PIPE_DISCONNECTED ); return; @@ -1180,6 +1198,8 @@ static struct sock *create_socket(void) sock->ifchange_obj = NULL; sock->accept_recv_req = NULL; sock->connect_req = NULL; + sock->rd_shutdown = 0; + sock->wr_shutdown = 0; sock->wr_shutdown_pending = 0; sock->nonblocking = 0; init_async_queue( &sock->read_q ); @@ -1339,7 +1359,6 @@ static int init_socket( struct sock *sock, int family, int type, int protocol, u } #endif
- sock->state = (type != SOCK_STREAM) ? (FD_READ|FD_WRITE) : 0; sock->flags = flags; sock->proto = protocol; sock->type = type; @@ -1404,7 +1423,7 @@ static struct sock *accept_socket( struct sock *sock ) }
/* newly created socket gets the same properties of the listening socket */ - acceptsock->state = FD_WINE_CONNECTED|FD_READ|FD_WRITE; + acceptsock->state = FD_WINE_CONNECTED; acceptsock->nonblocking = sock->nonblocking; acceptsock->mask = sock->mask; acceptsock->proto = sock->proto; @@ -1458,7 +1477,7 @@ static int accept_into_socket( struct sock *sock, struct sock *acceptsock ) return FALSE; }
- acceptsock->state |= FD_WINE_CONNECTED|FD_READ|FD_WRITE; + acceptsock->state |= FD_WINE_CONNECTED; acceptsock->pending_events = 0; acceptsock->reported_events = 0; acceptsock->proto = sock->proto; @@ -1808,7 +1827,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
if (!ret) { - sock->state |= FD_WINE_CONNECTED | FD_READ | FD_WRITE; + sock->state |= FD_WINE_CONNECTED; sock->state &= ~FD_CONNECT;
if (!send_len) return 1; @@ -1866,11 +1885,11 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
if (how != SD_SEND) { - sock->state &= ~FD_READ; + sock->rd_shutdown = 1; } if (how != SD_RECEIVE) { - sock->state &= ~FD_WRITE; + sock->wr_shutdown = 1; if (list_empty( &sock->write_q.queue )) shutdown( unix_fd, SHUT_WR ); else @@ -2462,8 +2481,7 @@ DECL_HANDLER(recv_socket) status = STATUS_PENDING; }
- /* are we shut down? */ - if (status == STATUS_PENDING && !(sock->state & FD_READ)) status = STATUS_PIPE_DISCONNECTED; + if (status == STATUS_PENDING && sock->rd_shutdown) status = STATUS_PIPE_DISCONNECTED;
sock->pending_events &= ~(req->oob ? FD_OOB : FD_READ); sock->reported_events &= ~(req->oob ? FD_OOB : FD_READ); @@ -2567,8 +2585,7 @@ DECL_HANDLER(send_socket) status = STATUS_PENDING; }
- /* are we shut down? */ - if (status == STATUS_PENDING && !(sock->state & FD_WRITE)) status = STATUS_PIPE_DISCONNECTED; + if (status == STATUS_PENDING && sock->wr_shutdown) status = STATUS_PIPE_DISCONNECTED;
if ((async = create_request_async( fd, get_fd_comp_flags( fd ), &req->async ))) {
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- include/winsock2.h | 5 -- server/sock.c | 191 +++++++++++++++++++++++++-------------------- 2 files changed, 107 insertions(+), 89 deletions(-)
diff --git a/include/winsock2.h b/include/winsock2.h index a10f81db668..abc82554d8e 100644 --- a/include/winsock2.h +++ b/include/winsock2.h @@ -291,11 +291,6 @@ extern "C" { #define FD_ROUTING_INTERFACE_CHANGE 0x00000100 #define FD_ADDRESS_LIST_CHANGE 0x00000200
-#ifdef __WINESRC__ -#define FD_WINE_LISTENING 0x10000000 -#define FD_WINE_CONNECTED 0x40000000 -#endif - /* Constants for LPCONDITIONPROC */ #define CF_ACCEPT 0x0000 #define CF_REJECT 0x0001 diff --git a/server/sock.c b/server/sock.c index 4cd84637baf..aa2c6842efc 100644 --- a/server/sock.c +++ b/server/sock.c @@ -131,11 +131,20 @@ struct connect_req unsigned int addr_len, send_len, send_cursor; };
+enum connection_state +{ + SOCK_LISTENING, + SOCK_UNCONNECTED, + SOCK_CONNECTING, + SOCK_CONNECTED, + SOCK_CONNECTIONLESS, +}; + struct sock { struct object obj; /* object header */ struct fd *fd; /* socket file descriptor */ - unsigned int state; /* status bits */ + enum connection_state state; /* connection state */ unsigned int mask; /* event mask */ /* pending FD_* events which have not yet been reported to the application */ unsigned int pending_events; @@ -603,8 +612,7 @@ static void complete_async_connect( struct sock *sock )
sock->pending_events &= ~(FD_CONNECT | FD_READ | FD_WRITE); sock->reported_events &= ~(FD_CONNECT | FD_READ | FD_WRITE); - sock->state |= FD_WINE_CONNECTED; - sock->state &= ~(FD_CONNECT | FD_WINE_LISTENING); + sock->state = SOCK_CONNECTED;
if (!req->send_len) { @@ -660,12 +668,12 @@ static int get_poll_flags( struct sock *sock, int event )
/* A connection-mode socket which has never been connected does not return * write or hangup events, but Linux reports POLLOUT | POLLHUP. */ - if (sock->type == WS_SOCK_STREAM && !(sock->state & (FD_CONNECT | FD_WINE_CONNECTED | FD_WINE_LISTENING))) + if (sock->state == SOCK_UNCONNECTED) event &= ~(POLLOUT | POLLHUP);
if (event & POLLIN) { - if (sock->state & FD_WINE_LISTENING) + if (sock->state == SOCK_LISTENING) flags |= AFD_POLL_ACCEPT; else flags |= AFD_POLL_READ; @@ -674,7 +682,7 @@ static int get_poll_flags( struct sock *sock, int event ) flags |= is_oobinline( sock ) ? AFD_POLL_READ : AFD_POLL_OOB; if (event & POLLOUT) flags |= AFD_POLL_WRITE; - if (sock->state & FD_WINE_CONNECTED) + if (sock->state == SOCK_CONNECTED) flags |= AFD_POLL_CONNECT; if (event & POLLHUP) flags |= AFD_POLL_HUP; @@ -816,32 +824,39 @@ static void post_socket_event( struct sock *sock, unsigned int event_bit, unsign } }
-static void sock_dispatch_events( struct sock *sock, int prevstate, int event, int error ) +static void sock_dispatch_events( struct sock *sock, enum connection_state prevstate, int event, int error ) { - if (prevstate & FD_CONNECT) + switch (prevstate) { - post_socket_event( sock, FD_CONNECT_BIT, sock_get_error( error ) ); - goto end; - } - if (prevstate & FD_WINE_LISTENING) - { - post_socket_event( sock, FD_ACCEPT_BIT, sock_get_error( error ) ); - goto end; + case SOCK_UNCONNECTED: + break; + + case SOCK_CONNECTING: + if (event & (POLLOUT | POLLERR | POLLHUP)) + post_socket_event( sock, FD_CONNECT_BIT, sock_get_error( error ) ); + break; + + case SOCK_LISTENING: + if (event & (POLLIN | POLLERR | POLLHUP)) + post_socket_event( sock, FD_ACCEPT_BIT, sock_get_error( error ) ); + break; + + case SOCK_CONNECTED: + case SOCK_CONNECTIONLESS: + if (event & POLLIN) + post_socket_event( sock, FD_READ_BIT, 0 ); + + if (event & POLLOUT) + post_socket_event( sock, FD_WRITE_BIT, 0 ); + + if (event & POLLPRI) + post_socket_event( sock, FD_OOB_BIT, 0 ); + + if (event & (POLLERR | POLLHUP)) + post_socket_event( sock, FD_CLOSE_BIT, sock_get_error( error ) ); + break; }
- if (event & POLLIN) - post_socket_event( sock, FD_READ_BIT, 0 ); - - if (event & POLLOUT) - post_socket_event( sock, FD_WRITE_BIT, 0 ); - - if (event & POLLPRI) - post_socket_event( sock, FD_OOB_BIT, 0 ); - - if (event & (POLLERR|POLLHUP)) - post_socket_event( sock, FD_CLOSE_BIT, sock_get_error( error ) ); - -end: sock_wake_up( sock ); }
@@ -849,7 +864,7 @@ static void sock_poll_event( struct fd *fd, int event ) { struct sock *sock = get_fd_user( fd ); int hangup_seen = 0; - int prevstate = sock->state; + enum connection_state prevstate = sock->state; int error = 0;
assert( sock->obj.ops == &sock_ops ); @@ -859,32 +874,32 @@ static void sock_poll_event( struct fd *fd, int event ) /* we may change event later, remove from loop here */ if (event & (POLLERR|POLLHUP)) set_fd_events( sock->fd, -1 );
- if (sock->state & FD_CONNECT) + switch (sock->state) { + case SOCK_UNCONNECTED: + break; + + case SOCK_CONNECTING: if (event & (POLLERR|POLLHUP)) { - /* we didn't get connected? */ - sock->state &= ~FD_CONNECT; + sock->state = SOCK_UNCONNECTED; event &= ~POLLOUT; error = sock_error( fd ); } else if (event & POLLOUT) { - /* we got connected */ - sock->state |= FD_WINE_CONNECTED; - sock->state &= ~FD_CONNECT; + sock->state = SOCK_CONNECTED; sock->connect_time = current_time; } - } - else if (sock->state & FD_WINE_LISTENING) - { - /* listening */ + break; + + case SOCK_LISTENING: if (event & (POLLERR|POLLHUP)) error = sock_error( fd ); - } - else - { - /* normal data flow */ + break; + + case SOCK_CONNECTED: + case SOCK_CONNECTIONLESS: if (sock->type == WS_SOCK_STREAM && (event & POLLIN)) { char dummy; @@ -926,6 +941,7 @@ static void sock_poll_event( struct fd *fd, int event )
if (hangup_seen) event |= POLLHUP; + break; }
complete_async_polls( sock, event, error ); @@ -952,7 +968,7 @@ static int poll_flags_from_afd( struct sock *sock, int flags ) /* A connection-mode socket which has never been connected does * not return write or hangup events, but Linux returns * POLLOUT | POLLHUP. */ - if (sock->type == WS_SOCK_STREAM && !(sock->state & (FD_CONNECT | FD_WINE_CONNECTED | FD_WINE_LISTENING))) + if (sock->state == SOCK_UNCONNECTED) return -1;
if (flags & (AFD_POLL_READ | AFD_POLL_ACCEPT)) @@ -979,41 +995,50 @@ static int sock_get_poll_events( struct fd *fd ) if (!sock->type) /* not initialized yet */ return -1;
- /* A connection-mode Windows socket which has never been connected does not - * return any events, but Linux returns POLLOUT | POLLHUP. Hence we need to - * return -1 here, to prevent the socket from being polled on at all. */ - if (sock->type == WS_SOCK_STREAM && !(sock->state & (FD_CONNECT | FD_WINE_CONNECTED | FD_WINE_LISTENING))) + switch (sock->state) + { + case SOCK_UNCONNECTED: + /* A connection-mode Windows socket which has never been connected does + * not return any events, but Linux returns POLLOUT | POLLHUP. Hence we + * need to return -1 here, to prevent the socket from being polled on at + * all. */ return -1;
- if (sock->state & FD_CONNECT) - /* connecting, wait for writable */ + case SOCK_CONNECTING: return POLLOUT;
- if (!list_empty( &sock->accept_list ) || sock->accept_recv_req ) - { - ev |= POLLIN | POLLPRI; - } - else if (async_queued( &sock->read_q )) - { - if (async_waiting( &sock->read_q )) ev |= POLLIN | POLLPRI; - } - else if (sock->state & FD_WINE_LISTENING) - { - if (mask & FD_ACCEPT) + case SOCK_LISTENING: + if (!list_empty( &sock->accept_list ) || (mask & FD_ACCEPT)) ev |= POLLIN; - } - else if (!sock->rd_shutdown && (mask & FD_READ)) - ev |= POLLIN | POLLPRI; - /* We use POLLIN with 0 bytes recv() as FD_CLOSE indication for stream sockets. */ - else if (sock->type == WS_SOCK_STREAM && (mask & FD_CLOSE) && !(sock->reported_events & FD_READ)) - ev |= POLLIN; + break;
- if (async_queued( &sock->write_q )) - { - if (async_waiting( &sock->write_q )) ev |= POLLOUT; + case SOCK_CONNECTED: + case SOCK_CONNECTIONLESS: + if (sock->accept_recv_req) + { + ev |= POLLIN; + } + else if (async_queued( &sock->read_q )) + { + if (async_waiting( &sock->read_q )) ev |= POLLIN | POLLPRI; + } + else if (!sock->rd_shutdown && (mask & FD_READ)) + ev |= POLLIN | POLLPRI; + /* We use POLLIN with 0 bytes recv() as FD_CLOSE indication for stream sockets. */ + else if (sock->state == SOCK_CONNECTED && (mask & FD_CLOSE) && !(sock->reported_events & FD_READ)) + ev |= POLLIN; + + if (async_queued( &sock->write_q )) + { + if (async_waiting( &sock->write_q )) ev |= POLLOUT; + } + else if (!sock->wr_shutdown && (mask & FD_WRITE)) + { + ev |= POLLOUT; + } + + break; } - else if (!sock->wr_shutdown && (mask & FD_WRITE)) - ev |= POLLOUT;
LIST_FOR_EACH_ENTRY( req, &poll_list, struct poll_req, entry ) { @@ -1067,8 +1092,7 @@ static void sock_queue_async( struct fd *fd, struct async *async, int type, int return; }
- if ( ( !( sock->state & (FD_CONNECT|FD_WINE_LISTENING) ) && type == ASYNC_TYPE_READ ) || - ( !( sock->state & (FD_CONNECT) ) && type == ASYNC_TYPE_WRITE ) ) + if (sock->state != SOCK_CONNECTED) { set_error( STATUS_PIPE_DISCONNECTED ); return; @@ -1181,7 +1205,7 @@ static struct sock *create_socket(void)
if (!(sock = alloc_object( &sock_ops ))) return NULL; sock->fd = NULL; - sock->state = 0; + sock->state = SOCK_UNCONNECTED; sock->mask = 0; sock->pending_events = 0; sock->reported_events = 0; @@ -1359,6 +1383,7 @@ static int init_socket( struct sock *sock, int family, int type, int protocol, u } #endif
+ sock->state = (type == WS_SOCK_STREAM ? SOCK_UNCONNECTED : SOCK_CONNECTIONLESS); sock->flags = flags; sock->proto = protocol; sock->type = type; @@ -1423,7 +1448,7 @@ static struct sock *accept_socket( struct sock *sock ) }
/* newly created socket gets the same properties of the listening socket */ - acceptsock->state = FD_WINE_CONNECTED; + acceptsock->state = SOCK_CONNECTED; acceptsock->nonblocking = sock->nonblocking; acceptsock->mask = sock->mask; acceptsock->proto = sock->proto; @@ -1477,7 +1502,7 @@ static int accept_into_socket( struct sock *sock, struct sock *acceptsock ) return FALSE; }
- acceptsock->state |= FD_WINE_CONNECTED; + acceptsock->state = SOCK_CONNECTED; acceptsock->pending_events = 0; acceptsock->reported_events = 0; acceptsock->proto = sock->proto; @@ -1765,8 +1790,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
sock->pending_events &= ~FD_ACCEPT; sock->reported_events &= ~FD_ACCEPT; - sock->state |= FD_WINE_LISTENING; - sock->state &= ~(FD_CONNECT | FD_WINE_CONNECTED); + sock->state = SOCK_LISTENING;
/* a listening socket can no longer be accepted into */ allow_fd_caching( sock->fd ); @@ -1804,7 +1828,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) return 0; }
- if (sock->state & FD_CONNECT) + if (sock->state == SOCK_CONNECTING) { /* FIXME: STATUS_ADDRESS_ALREADY_ASSOCIATED probably isn't right, * but there's no status code that maps to WSAEALREADY... */ @@ -1827,8 +1851,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
if (!ret) { - sock->state |= FD_WINE_CONNECTED; - sock->state &= ~FD_CONNECT; + sock->state = SOCK_CONNECTED;
if (!send_len) return 1; } @@ -1836,7 +1859,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) if (!(req = mem_alloc( sizeof(*req) ))) return 0;
- sock->state |= FD_CONNECT; + sock->state = SOCK_CONNECTING;
if (params->synchronous && sock->nonblocking) { @@ -1877,7 +1900,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) return 0; }
- if (sock->type == WS_SOCK_STREAM && !(sock->state & FD_WINE_CONNECTED)) + if (sock->state != SOCK_CONNECTED && sock->state != SOCK_CONNECTIONLESS) { set_error( STATUS_INVALID_CONNECTION ); return 0;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- server/sock.c | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/server/sock.c b/server/sock.c index aa2c6842efc..827eba52117 100644 --- a/server/sock.c +++ b/server/sock.c @@ -610,8 +610,6 @@ static void complete_async_connect( struct sock *sock )
if (debug_level) fprintf( stderr, "completing connect request for socket %p\n", sock );
- sock->pending_events &= ~(FD_CONNECT | FD_READ | FD_WRITE); - sock->reported_events &= ~(FD_CONNECT | FD_READ | FD_WRITE); sock->state = SOCK_CONNECTED;
if (!req->send_len) @@ -1846,9 +1844,6 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) /* a connected or connecting socket can no longer be accepted into */ allow_fd_caching( sock->fd );
- sock->pending_events &= ~(FD_CONNECT | FD_READ | FD_WRITE); - sock->reported_events &= ~(FD_CONNECT | FD_READ | FD_WRITE); - if (!ret) { sock->state = SOCK_CONNECTED;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- server/sock.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/server/sock.c b/server/sock.c index 827eba52117..66440a540dc 100644 --- a/server/sock.c +++ b/server/sock.c @@ -1786,8 +1786,6 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) return 0; }
- sock->pending_events &= ~FD_ACCEPT; - sock->reported_events &= ~FD_ACCEPT; sock->state = SOCK_LISTENING;
/* a listening socket can no longer be accepted into */