diff --git a/lib/core-net/close.c b/lib/core-net/close.c index e8f756788..be113b4ef 100644 --- a/lib/core-net/close.c +++ b/lib/core-net/close.c @@ -275,6 +275,9 @@ __lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason, context = wsi->a.context; pt = &context->pt[(int)wsi->tsi]; + + lws_pt_assert_lock_held(pt); + lws_stats_bump(pt, LWSSTATS_C_API_CLOSE, 1); #if defined(LWS_WITH_CLIENT) diff --git a/lib/core-net/pollfd.c b/lib/core-net/pollfd.c index eaeda9420..894d7772a 100644 --- a/lib/core-net/pollfd.c +++ b/lib/core-net/pollfd.c @@ -271,6 +271,8 @@ __insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi) // __dump_fds(pt, "pre insert"); + lws_pt_assert_lock_held(pt); + lwsl_debug("%s: %p: tsi=%d, sock=%d, pos-in-fds=%d\n", __func__, wsi, wsi->tsi, wsi->desc.sockfd, pt->fds_count); @@ -352,6 +354,8 @@ __remove_wsi_socket_from_fds(struct lws *wsi) struct lws *end_wsi; int v, m, ret = 0; + lws_pt_assert_lock_held(pt); + // __dump_fds(pt, "pre remove"); #if !defined(_WIN32) diff --git a/lib/core-net/private-lib-core-net.h b/lib/core-net/private-lib-core-net.h index 05ca1e700..ea785c509 100644 --- a/lib/core-net/private-lib-core-net.h +++ b/lib/core-net/private-lib-core-net.h @@ -999,6 +999,7 @@ lws_pt_mutex_destroy(struct lws_context_per_thread *pt) #define lws_pt_lock(pt, reason) lws_mutex_refcount_lock(&pt->mr, reason) #define lws_pt_unlock(pt) lws_mutex_refcount_unlock(&pt->mr) +#define lws_pt_assert_lock_held(pt) lws_mutex_refcount_assert_held(&pt->mr) static LWS_INLINE void lws_pt_stats_lock(struct lws_context_per_thread *pt) diff --git a/lib/core-net/vhost.c b/lib/core-net/vhost.c index 09cb979a3..5e01967d6 100644 --- a/lib/core-net/vhost.c +++ b/lib/core-net/vhost.c @@ -908,6 +908,7 @@ lws_cancel_service(struct lws_context *context) int lws_create_event_pipes(struct lws_context *context) { + struct lws_context_per_thread *pt; size_t s = sizeof(struct lws); struct lws *wsi; int n; @@ -923,7 +924,9 @@ lws_create_event_pipes(struct lws_context *context) n = 0; { #endif - if (context->pt[n].pipe_wsi) + pt = &context->pt[n]; + + if (pt->pipe_wsi) return 0; #if defined(LWS_WITH_EVENT_LIBS) @@ -948,6 +951,8 @@ lws_create_event_pipes(struct lws_context *context) context->pt[n].pipe_wsi = wsi; context->count_wsi_allocated++; + lws_pt_lock(pt, __func__); /* -------------- pt { */ + if (!lws_plat_pipe_create(wsi)) { /* * platform code returns 0 if it actually created pipes @@ -963,14 +968,21 @@ lws_create_event_pipes(struct lws_context *context) if (context->event_loop_ops->sock_accept) if (context->event_loop_ops->sock_accept(wsi)) - return 1; + goto bail; if (__insert_wsi_socket_into_fds(context, wsi)) - return 1; + goto bail; } + + lws_pt_unlock(pt); } return 0; + +bail: + lws_pt_unlock(pt); + + return 1; } void diff --git a/lib/core-net/wsi-timeout.c b/lib/core-net/wsi-timeout.c index f3610a5b2..f6b9fac75 100644 --- a/lib/core-net/wsi-timeout.c +++ b/lib/core-net/wsi-timeout.c @@ -118,7 +118,9 @@ lws_sul_wsitimeout_cb(lws_sorted_usec_list_t *sul) (void *)"Timed out waiting SSL", 21); #endif + lws_pt_lock(pt, __func__); __lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "timeout"); + lws_pt_unlock(pt); } void diff --git a/lib/core/context.c b/lib/core/context.c index 85f77b0f4..d25e9161b 100644 --- a/lib/core/context.c +++ b/lib/core/context.c @@ -1540,8 +1540,10 @@ lws_pt_destroy(struct lws_context_per_thread *pt) } vpt->foreign_pfd_list = NULL; + lws_pt_lock(pt, __func__); if (pt->pipe_wsi) lws_destroy_event_pipe(pt->pipe_wsi); + lws_pt_unlock(pt); pt->pipe_wsi = NULL; while (pt->fds_count) { diff --git a/lib/core/libwebsockets.c b/lib/core/libwebsockets.c index e3b7c954d..a44e6d5f5 100644 --- a/lib/core/libwebsockets.c +++ b/lib/core/libwebsockets.c @@ -1194,6 +1194,12 @@ lws_mutex_refcount_unlock(struct lws_mutex_refcount *mr) pthread_mutex_unlock(&mr->lock); } +void +lws_mutex_refcount_assert_held(struct lws_mutex_refcount *mr) +{ + assert(mr->lock_owner == pthread_self() && mr->lock_depth); +} + #endif /* SMP */ diff --git a/lib/core/private-lib-core.h b/lib/core/private-lib-core.h index ca82651a9..b4dcf7050 100644 --- a/lib/core/private-lib-core.h +++ b/lib/core/private-lib-core.h @@ -250,6 +250,9 @@ lws_mutex_refcount_destroy(struct lws_mutex_refcount *mr); void lws_mutex_refcount_lock(struct lws_mutex_refcount *mr, const char *reason); +void +lws_mutex_refcount_assert_held(struct lws_mutex_refcount *mr); + void lws_mutex_refcount_unlock(struct lws_mutex_refcount *mr); #endif @@ -644,6 +647,7 @@ lws_vhost_unlock(struct lws_vhost *vhost) #define lws_pt_mutex_init(_a) (void)(_a) #define lws_pt_mutex_destroy(_a) (void)(_a) #define lws_pt_lock(_a, b) (void)(_a) +#define lws_pt_assert_lock_held(_a) (void)(_a) #define lws_pt_unlock(_a) (void)(_a) #define lws_context_lock(_a, _b) (void)(_a) #define lws_context_unlock(_a) (void)(_a) diff --git a/lib/roles/http/server/server.c b/lib/roles/http/server/server.c index 01a6b38bc..c8683fc05 100644 --- a/lib/roles/http/server/server.c +++ b/lib/roles/http/server/server.c @@ -52,6 +52,7 @@ int _lws_vhost_init_server(const struct lws_context_creation_info *info, struct lws_vhost *vhost) { + struct lws_context_per_thread *pt; int n, opt = 1, limit = 1; lws_sockfd_type sockfd; struct lws_vhost *vh; @@ -309,13 +310,18 @@ done_list: if (wsi->a.context->event_loop_ops->init_vhost_listen_wsi) wsi->a.context->event_loop_ops->init_vhost_listen_wsi(wsi); + pt = &vhost->context->pt[m]; + lws_pt_lock(pt, __func__); + if (__insert_wsi_socket_into_fds(vhost->context, wsi)) { lwsl_notice("inserting wsi socket into fds failed\n"); + lws_pt_unlock(pt); goto bail; } vhost->context->count_wsi_allocated++; vhost->lserv_wsi = wsi; + lws_pt_unlock(pt); n = listen(wsi->desc.sockfd, LWS_SOMAXCONN); if (n < 0) {