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

adopt readbuf do service

Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
Andy Green 2016-02-27 11:42:22 +08:00
parent ee699c0036
commit e3d141dae9
8 changed files with 74 additions and 28 deletions

View file

@ -303,7 +303,7 @@ lws_client_connect_2(struct lws *wsi)
oom4:
/* we're closing, losing some rx is OK */
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
lws_header_table_detach(wsi);
lws_header_table_detach(wsi, 0);
lws_free(wsi);
return NULL;
@ -405,7 +405,7 @@ lws_client_connect_via_info(struct lws_client_connect_info *i)
}
#endif
if (lws_header_table_attach(wsi))
if (lws_header_table_attach(wsi, 0))
goto bail;
/*
@ -470,7 +470,7 @@ lws_client_connect_via_info(struct lws_client_connect_info *i)
bail1:
/* we're closing, losing some rx is OK */
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
lws_header_table_detach(wsi);
lws_header_table_detach(wsi, 0);
bail:
lws_free(wsi);

View file

@ -798,7 +798,7 @@ check_accept:
lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
/* free up his parsing allocations */
lws_header_table_detach(wsi);
lws_header_table_detach(wsi, 0);
lws_union_transition(wsi, LWSCM_WS_CLIENT);
wsi->state = LWSS_ESTABLISHED;

View file

@ -80,7 +80,7 @@ lws_uv_timeout_cb(uv_timer_t *timer)
struct lws_context_per_thread *pt = container_of(timer,
struct lws_context_per_thread, uv_timeout_watcher);
lwsl_info("%s\n", __func__);
lwsl_debug("%s\n", __func__);
/* do timeout check only */
lws_service_fd_tsi(pt->context, NULL, pt->tid);
}
@ -119,8 +119,10 @@ lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, uv_signal_cb cb,
*/
if (wsi) {
wsi->w_read.context = context;
uv_poll_init(pt->io_loop_uv, &wsi->w_read.uv_watcher, pt->lserv_fd);
uv_poll_start(&wsi->w_read.uv_watcher, UV_READABLE, lws_accept_cb);
uv_poll_init(pt->io_loop_uv, &wsi->w_read.uv_watcher,
pt->lserv_fd);
uv_poll_start(&wsi->w_read.uv_watcher, UV_READABLE,
lws_accept_cb);
}
uv_timer_init(pt->io_loop_uv, &pt->uv_timeout_watcher);

View file

@ -63,7 +63,7 @@ lws_free_wsi(struct lws *wsi)
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
/* we may not have an ah, but may be on the waiting list... */
lws_header_table_detach(wsi);
lws_header_table_detach(wsi, 0);
wsi->context->count_wsi_allocated--;
lwsl_debug("%s: %p, remaining wsi %d\n", __func__, wsi,

View file

@ -61,9 +61,11 @@ lextable_decode(int pos, char c)
}
void
lws_header_table_reset(struct lws *wsi)
lws_header_table_reset(struct lws *wsi, int autoservice)
{
struct allocated_headers *ah = wsi->u.hdr.ah;
struct lws_context_per_thread *pt;
struct lws_pollfd *pfd;
/* if we have the idea we're resetting 'our' ah, must be bound to one */
assert(ah);
@ -87,14 +89,29 @@ lws_header_table_reset(struct lws *wsi)
* processing), apply and free it.
*/
if (wsi->u.hdr.preamble_rx) {
memcpy(ah->rx, wsi->u.hdr.preamble_rx, wsi->u.hdr.preamble_rx_len);
memcpy(ah->rx, wsi->u.hdr.preamble_rx,
wsi->u.hdr.preamble_rx_len);
ah->rxlen = wsi->u.hdr.preamble_rx_len;
lws_free_set_NULL(wsi->u.hdr.preamble_rx);
if (autoservice) {
lwsl_notice("%s: calling service on readbuf ah\n", __func__);
pt = &wsi->context->pt[(int)wsi->tsi];
/* unlike a normal connect, we have the headers already
* (or the first part of them anyway)
*/
pfd = &pt->fds[wsi->position_in_fds_table];
pfd->revents |= LWS_POLLIN;
lwsl_err("%s: calling service\n", __func__);
lws_service_fd_tsi(wsi->context, pfd, wsi->tsi);
}
}
}
int LWS_WARN_UNUSED_RESULT
lws_header_table_attach(struct lws *wsi)
lws_header_table_attach(struct lws *wsi, int autoservice)
{
struct lws_context *context = wsi->context;
struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
@ -165,7 +182,7 @@ lws_header_table_attach(struct lws *wsi)
lws_pt_unlock(pt);
reset:
lws_header_table_reset(wsi);
lws_header_table_reset(wsi, autoservice);
time(&wsi->u.hdr.ah->assigned);
return 0;
@ -176,7 +193,7 @@ bail:
return 1;
}
int lws_header_table_detach(struct lws *wsi)
int lws_header_table_detach(struct lws *wsi, int autoservice)
{
struct lws_context *context = wsi->context;
struct allocated_headers *ah = wsi->u.hdr.ah;
@ -258,7 +275,7 @@ int lws_header_table_detach(struct lws *wsi)
wsi->u.hdr.ah = ah;
ah->wsi = wsi; /* new owner */
lws_header_table_reset(wsi);
lws_header_table_reset(wsi, autoservice);
time(&wsi->u.hdr.ah->assigned);
assert(wsi->position_in_fds_table != -1);

View file

@ -1296,13 +1296,13 @@ LWS_EXTERN int
lws_plat_set_socket_options(struct lws_context *context, lws_sockfd_type fd);
LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_header_table_attach(struct lws *wsi);
lws_header_table_attach(struct lws *wsi, int autoservice);
LWS_EXTERN int
lws_header_table_detach(struct lws *wsi);
lws_header_table_detach(struct lws *wsi, int autoservice);
LWS_EXTERN void
lws_header_table_reset(struct lws *wsi);
lws_header_table_reset(struct lws *wsi, int autoservice);
LWS_EXTERN char * LWS_WARN_UNUSED_RESULT
lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h);

View file

@ -330,7 +330,7 @@ lws_http_action(struct lws *wsi)
bail_nuke_ah:
/* we're closing, losing some rx is OK */
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
lws_header_table_detach(wsi);
lws_header_table_detach(wsi, 1);
return 1;
}
@ -628,7 +628,7 @@ bail_nuke_ah:
/* drop the header info */
/* we're closing, losing some rx is OK */
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
lws_header_table_detach(wsi);
lws_header_table_detach(wsi, 1);
return 1;
}
@ -753,9 +753,9 @@ lws_http_transaction_completed(struct lws *wsi)
if (!wsi->more_rx_waiting) {
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
lws_header_table_detach(wsi);
lws_header_table_detach(wsi, 1);
} else
lws_header_table_reset(wsi);
lws_header_table_reset(wsi, 1);
}
/* If we're (re)starting on headers, need other implied init */
@ -861,7 +861,9 @@ lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
const char *readbuf, size_t len)
{
struct lws *wsi = lws_adopt_socket(context, accept_fd);
struct lws_context_per_thread *pt;
struct allocated_headers *ah;
struct lws_pollfd *pfd;
if (!wsi)
return NULL;
@ -878,24 +880,42 @@ lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
*
* if one is available, get it and place the data in his ah rxbuf...
* wsi with ah that have pending rxbuf get auto-POLLIN service.
*
* no autoservice because we didn't get a chance to attach the
* readbuf data to wsi or ah yet, and we will do it next if we get
* the ah.
*/
if (!lws_header_table_attach(wsi)) {
if (!lws_header_table_attach(wsi, 0)) {
ah = wsi->u.hdr.ah;
memcpy(ah->rx, readbuf, len);
ah->rxpos = 0;
ah->rxlen = len;
lwsl_notice("%s: calling service on readbuf ah\n", __func__);
pt = &context->pt[(int)wsi->tsi];
/* unlike a normal connect, we have the headers already
* (or the first part of them anyway).
* libuv won't come back and service us without a network
* event, so we need to do the header service right here.
*/
pfd = &pt->fds[wsi->position_in_fds_table];
pfd->revents |= LWS_POLLIN;
lwsl_err("%s: calling service\n", __func__);
if (lws_service_fd_tsi(context, pfd, wsi->tsi))
/* service closed us */
return NULL;
return wsi;
}
lwsl_err("%s: deferring handling ah\n", __func__);
/*
* hum if no ah came, we are on the wait list and must defer
* dealing with this until the ah arrives.
*
* later successful lws_header_table_attach() will apply the
* below to the rx buffer.
* below to the rx buffer (via lws_header_table_reset()).
*/
wsi->u.hdr.preamble_rx = lws_malloc(len);
memcpy(wsi->u.hdr.preamble_rx, readbuf, len);
wsi->u.hdr.preamble_rx_len = len;
@ -958,7 +978,8 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
wsi->state == LWSS_HTTP_ISSUING_FILE ||
wsi->state == LWSS_HTTP_HEADERS) {
if (!wsi->u.hdr.ah)
if (lws_header_table_attach(wsi))
/* no autoservice beacuse we will do it next */
if (lws_header_table_attach(wsi, 0))
goto try_pollout;
ah = wsi->u.hdr.ah;
@ -1002,7 +1023,7 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
(wsi->mode != LWSCM_HTTP_SERVING &&
wsi->mode != LWSCM_HTTP_SERVING_ACCEPTED &&
wsi->mode != LWSCM_HTTP2_SERVING))
lws_header_table_detach(wsi);
lws_header_table_detach(wsi, 1);
}
break;
}
@ -1052,6 +1073,9 @@ try_pollout:
goto fail;
}
if (!wsi->hdr_parsing_completed)
break;
if (wsi->state != LWSS_HTTP_ISSUING_FILE) {
n = user_callback_handle_rxflow(wsi->protocol->callback,
wsi, LWS_CALLBACK_HTTP_WRITEABLE,

View file

@ -237,6 +237,9 @@ user_service:
return 1;
}
if (!wsi->hdr_parsing_completed)
return 0;
#ifdef LWS_USE_HTTP2
/*
* we are the 'network wsi' for potentially many muxed child wsi with
@ -789,7 +792,7 @@ drain:
/* we can run the normal ah detach flow despite
* being in ws union mode, since all union members
* start with hdr */
lws_header_table_detach(wsi);
lws_header_table_detach(wsi, 0);
}
pending = lws_ssl_pending(wsi);