pmd: handle case we are already on drain list

Provide internal helper for adding to list that takes care of the
case we are already on the list.

https://github.com/warmcat/libwebsockets/issues/847
This commit is contained in:
Andy Green 2017-03-26 10:08:35 +08:00
parent 7aadd14398
commit d58353f98a
5 changed files with 35 additions and 15 deletions

View file

@ -28,7 +28,6 @@
int lws_client_rx_sm(struct lws *wsi, unsigned char c)
{
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
int callback_action = LWS_CALLBACK_CLIENT_RECEIVE;
int handled, n, m, rx_draining_ext = 0;
unsigned short close_code;
@ -548,17 +547,14 @@ utf8_fail: lwsl_info("utf8 error\n");
if (callback_action == LWS_CALLBACK_CLIENT_RECEIVE_PONG)
lwsl_info("Client doing pong callback\n");
if (n && eff_buf.token_len) {
if (n && eff_buf.token_len)
/* extension had more... main loop will come back
* we want callback to be done with this set, if so,
* because lws_is_final() hides it was final until the
* last chunk
*/
wsi->u.ws.rx_draining_ext = 1;
wsi->u.ws.rx_draining_ext_list = pt->rx_draining_ext_list;
pt->rx_draining_ext_list = wsi;
lwsl_ext("%s: RX EXT DRAINING: Adding to list\n", __func__);
} else
lws_add_wsi_to_draining_ext_list(wsi);
else
lws_remove_wsi_from_draining_ext_list(wsi);
if (wsi->state == LWSS_RETURNED_CLOSE_ALREADY ||

View file

@ -954,16 +954,39 @@ LWS_VISIBLE int lws_frame_is_binary(struct lws *wsi)
{
return wsi->u.ws.frame_is_binary;
}
void
lws_add_wsi_to_draining_ext_list(struct lws *wsi)
{
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
if (wsi->u.ws.rx_draining_ext)
return;
lwsl_ext("%s: RX EXT DRAINING: Adding to list\n", __func__);
wsi->u.ws.rx_draining_ext = 1;
wsi->u.ws.rx_draining_ext_list = pt->rx_draining_ext_list;
pt->rx_draining_ext_list = wsi;
}
void
lws_remove_wsi_from_draining_ext_list(struct lws *wsi)
{
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
struct lws **w = &pt->rx_draining_ext_list;
if (!wsi->u.ws.rx_draining_ext)
return;
lwsl_ext("%s: RX EXT DRAINING: Removing from list\n", __func__);
wsi->u.ws.rx_draining_ext = 0;
/* remove us from context draining ext list */
while (*w) {
if (*w == wsi) {
/* if us, point it instead to who we were pointing to */
*w = wsi->u.ws.rx_draining_ext_list;
break;
}
@ -980,7 +1003,6 @@ lws_remove_wsi_from_draining_ext_list(struct lws *wsi)
int
lws_rx_sm(struct lws *wsi, unsigned char c)
{
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
int callback_action = LWS_CALLBACK_RECEIVE;
int ret = 0, n, rx_draining_ext = 0;
struct lws_tokens eff_buf;
@ -1445,10 +1467,7 @@ drain_extension:
if (n && eff_buf.token_len) {
/* extension had more... main loop will come back */
// lwsl_notice("ext has stuff to drain\n");
wsi->u.ws.rx_draining_ext = 1;
wsi->u.ws.rx_draining_ext_list = pt->rx_draining_ext_list;
pt->rx_draining_ext_list = wsi;
lws_add_wsi_to_draining_ext_list(wsi);
} else
lws_remove_wsi_from_draining_ext_list(wsi);

View file

@ -2033,6 +2033,8 @@ LWS_EXTERN int
lws_plat_change_pollfd(struct lws_context *context, struct lws *wsi,
struct lws_pollfd *pfd);
LWS_EXTERN void
lws_add_wsi_to_draining_ext_list(struct lws *wsi);
LWS_EXTERN void
lws_remove_wsi_from_draining_ext_list(struct lws *wsi);
LWS_EXTERN int
lws_plat_context_early_init(void);

View file

@ -496,9 +496,10 @@ lws_service_flag_pending(struct lws_context *context, int tsi)
while (wsi) {
pt->fds[wsi->position_in_fds_table].revents |=
pt->fds[wsi->position_in_fds_table].events & LWS_POLLIN;
if (pt->fds[wsi->position_in_fds_table].revents &
LWS_POLLIN)
if (pt->fds[wsi->position_in_fds_table].revents & LWS_POLLIN) {
forced = 1;
break;
}
wsi = wsi->u.ws.rx_draining_ext_list;
}

File diff suppressed because one or more lines are too long