1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-30 00:00:16 +01:00

clear down wsi_lookup on allocation and clear pollfd revents if serviced

This should get rid of a valgrind uninitialized report when using extpoll,
and gives a new way to share the poll loop with external sockets.

If a pollfd says it has something, you can just pass it to
libwebsocket_serice_fd() whether it is a socket handled by lws or not.
If it sees it is a lws socket, the traffic will be handled and
pollfd->revents will be zeroed now.

If the socket is foreign to lws, it leaves revents alone.  So you can see
if you should service by checking the pollfd revents after letting
lws try to service it.

Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
Andy Green 2013-03-09 12:34:30 +08:00
parent 25eddab5c8
commit b1a5e6c377

View file

@ -874,9 +874,12 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
if (libwebsocket_service_timeout_check(context, wsi, if (libwebsocket_service_timeout_check(context, wsi,
tv.tv_sec)) tv.tv_sec))
/* he did time out... */ /* he did time out... */
if (m == our_fd) if (m == our_fd) {
/* it was the guy we came to service! */ /* it was the guy we came to service! */
timed_out = 1; timed_out = 1;
/* mark as handled */
pollfd->revents = 0;
}
} }
} }
@ -891,6 +894,16 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
/* no, here to service a socket descriptor */ /* no, here to service a socket descriptor */
wsi = context->lws_lookup[pollfd->fd];
if (wsi == NULL)
/* not lws connection ... leave revents alone and return */
return 0;
/*
* so that caller can tell we handled, past here we need to
* zero down pollfd->revents after handling
*/
/* /*
* deal with listen service piggybacking * deal with listen service piggybacking
* every listen_service_modulo services of other fds, we * every listen_service_modulo services of other fds, we
@ -935,21 +948,14 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
/* okay, what we came here to do... */ /* okay, what we came here to do... */
wsi = context->lws_lookup[pollfd->fd];
if (wsi == NULL) {
if (pollfd->fd > 11)
lwsl_err("unexpected NULL wsi fd=%d fds_count=%d\n",
pollfd->fd, context->fds_count);
return 0;
}
switch (wsi->mode) { switch (wsi->mode) {
#ifndef LWS_NO_SERVER #ifndef LWS_NO_SERVER
case LWS_CONNMODE_HTTP_SERVING: case LWS_CONNMODE_HTTP_SERVING:
case LWS_CONNMODE_SERVER_LISTENER: case LWS_CONNMODE_SERVER_LISTENER:
case LWS_CONNMODE_SSL_ACK_PENDING: case LWS_CONNMODE_SSL_ACK_PENDING:
return lws_server_socket_service(context, wsi, pollfd); n = lws_server_socket_service(context, wsi, pollfd);
goto handled;
#endif #endif
case LWS_CONNMODE_WS_SERVING: case LWS_CONNMODE_WS_SERVING:
@ -963,9 +969,7 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
lwsl_debug("Session Socket %p (fd=%d) dead\n", lwsl_debug("Session Socket %p (fd=%d) dead\n",
(void *)wsi, pollfd->fd); (void *)wsi, pollfd->fd);
libwebsocket_close_and_free_session(context, wsi, goto close_and_handled;
LWS_CLOSE_STATUS_NOSTATUS);
return 0;
} }
/* the guy requested a callback when it was OK to write */ /* the guy requested a callback when it was OK to write */
@ -975,9 +979,7 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
if (lws_handle_POLLOUT_event(context, wsi, if (lws_handle_POLLOUT_event(context, wsi,
pollfd) < 0) { pollfd) < 0) {
lwsl_info("libwebsocket_service_fd: closing\n"); lwsl_info("libwebsocket_service_fd: closing\n");
libwebsocket_close_and_free_session( goto close_and_handled;
context, wsi, LWS_CLOSE_STATUS_NOSTATUS);
return 0;
} }
@ -1008,15 +1010,13 @@ read_pending:
lwsl_debug("Socket read returned %d\n", lwsl_debug("Socket read returned %d\n",
eff_buf.token_len); eff_buf.token_len);
if (errno != EINTR && errno != EAGAIN) if (errno != EINTR && errno != EAGAIN)
libwebsocket_close_and_free_session(context, goto close_and_handled;
wsi, LWS_CLOSE_STATUS_NOSTATUS); n = 0;
return 0; goto handled;
} }
if (!eff_buf.token_len) { if (!eff_buf.token_len) {
lwsl_info("closing connection due to 0 length read\n"); lwsl_info("closing connection due to 0 length read\n");
libwebsocket_close_and_free_session(context, wsi, goto close_and_handled;
LWS_CLOSE_STATUS_NOSTATUS);
return 0;
} }
/* /*
@ -1047,10 +1047,7 @@ read_pending:
if (m < 0) { if (m < 0) {
lwsl_ext( lwsl_ext(
"Extension reports fatal error\n"); "Extension reports fatal error\n");
libwebsocket_close_and_free_session( goto close_and_handled;
context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
return 0;
} }
if (m) if (m)
more = 1; more = 1;
@ -1062,9 +1059,11 @@ read_pending:
n = libwebsocket_read(context, wsi, n = libwebsocket_read(context, wsi,
(unsigned char *)eff_buf.token, (unsigned char *)eff_buf.token,
eff_buf.token_len); eff_buf.token_len);
if (n < 0) if (n < 0) {
/* we closed wsi */ /* we closed wsi */
return 0; n = 0;
goto handled;
}
} }
#ifndef LWS_NO_EXTENSIONS #ifndef LWS_NO_EXTENSIONS
eff_buf.token = NULL; eff_buf.token = NULL;
@ -1082,11 +1081,23 @@ read_pending:
#ifdef LWS_NO_CLIENT #ifdef LWS_NO_CLIENT
break; break;
#else #else
return lws_client_socket_service(context, wsi, pollfd); n = lws_client_socket_service(context, wsi, pollfd);
goto handled;
#endif #endif
} }
return 0; n = 0;
goto handled;
close_and_handled:
libwebsocket_close_and_free_session(
context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
n = 0;
handled:
pollfd->revents = 0;
return n;
} }
@ -1750,6 +1761,8 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
free(context); free(context);
return NULL; return NULL;
} }
memset(context->lws_lookup, 0, sizeof(struct libwebsocket *) *
context->max_fds);
context->fds_count = 0; context->fds_count = 0;
#ifndef LWS_NO_EXTENSIONS #ifndef LWS_NO_EXTENSIONS