From: Andy Green Date: Fri, 23 Jun 2017 02:27:52 +0000 (+0800) Subject: client: add libuv support to lws_client_reset X-Git-Tag: accepted/tizen/4.0/unified/20171012.191640~73 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fupstream%2Flibwebsockets.git;a=commitdiff_plain;h=ede9ad2b1302f15d6885e178e4290ef9dcd5d62d client: add libuv support to lws_client_reset More direct solution to problem described in https://github.com/warmcat/libwebsockets/pull/940 --- diff --git a/lib/client-handshake.c b/lib/client-handshake.c index 6286f2d..4fb9d4c 100644 --- a/lib/client-handshake.c +++ b/lib/client-handshake.c @@ -203,6 +203,15 @@ lws_client_connect_2(struct lws *wsi) if (!lws_socket_is_valid(wsi->desc.sockfd)) { +#if defined(LWS_USE_LIBUV) + if (LWS_LIBUV_ENABLED(context)) + if (lws_libuv_check_watcher_active(wsi)) { + lwsl_warn("Waiting for libuv watcher to close\n"); + cce = "waiting for libuv watcher to close"; + goto oom4; + } +#endif + #ifdef LWS_USE_IPV6 if (wsi->ipv6) { sa46.sa6.sin6_port = htons(port); @@ -232,6 +241,7 @@ lws_client_connect_2(struct lws *wsi) lws_libev_accept(wsi, wsi->desc); lws_libuv_accept(wsi, wsi->desc); lws_libevent_accept(wsi, wsi->desc); + if (insert_wsi_socket_into_fds(context, wsi)) { compatible_close(wsi->desc.sockfd); cce = "insert wsi failed"; @@ -474,7 +484,22 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port, /* close the connection by hand */ +#ifdef LWS_USE_LIBUV + if (LWS_LIBUV_ENABLED(wsi->context)) { + lwsl_debug("%s: lws_libuv_closehandle: wsi %p\n", __func__, wsi); + /* + * libuv has to do his own close handle processing asynchronously + * but once it starts we can do everything else synchronously, + * including trash wsi->desc.sockfd since it took a copy. + * + * When it completes it will call compatible_close() + */ + lws_libuv_closehandle_manually(wsi); + } else +#else compatible_close(wsi->desc.sockfd); +#endif + remove_wsi_socket_from_fds(wsi); wsi->desc.sockfd = LWS_SOCK_INVALID; diff --git a/lib/libuv.c b/lib/libuv.c index e295ee3..c0d5aa3 100644 --- a/lib/libuv.c +++ b/lib/libuv.c @@ -520,13 +520,39 @@ lws_libuv_closehandle(struct lws *wsi) struct lws_context *context = lws_get_context(wsi); /* required to defer actual deletion until libuv has processed it */ - uv_close((uv_handle_t*)&wsi->w_read.uv_watcher, lws_libuv_closewsi); if (context->requested_kill && context->count_wsi_allocated == 0) lws_libuv_kill(context); } +static void +lws_libuv_closewsi_m(uv_handle_t* handle) +{ + lws_sockfd_type sockfd = (lws_sockfd_type)(long long)handle->data; + + compatible_close(sockfd); +} + +void +lws_libuv_closehandle_manually(struct lws *wsi) +{ + uv_handle_t *h = (void *)&wsi->w_read.uv_watcher; + + h->data = (void *)(long long)wsi->desc.sockfd; + /* required to defer actual deletion until libuv has processed it */ + uv_close((uv_handle_t*)&wsi->w_read.uv_watcher, lws_libuv_closewsi_m); +} + +int +lws_libuv_check_watcher_active(struct lws *wsi) +{ + uv_handle_t *h = (void *)&wsi->w_read.uv_watcher; + + return uv_is_active(h); +} + + #if defined(LWS_WITH_PLUGINS) && (UV_VERSION_MAJOR > 0) LWS_VISIBLE int diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index dc6146c..1cee7c2 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -1035,6 +1035,10 @@ LWS_EXTERN void lws_close_free_wsi_final(struct lws *wsi); LWS_EXTERN void lws_libuv_closehandle(struct lws *wsi); +LWS_EXTERN void +lws_libuv_closehandle_manually(struct lws *wsi); +LWS_EXTERN int +lws_libuv_check_watcher_active(struct lws *wsi); LWS_VISIBLE LWS_EXTERN int lws_plat_plugins_init(struct lws_context * context, const char * const *d);