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

Add locking into the cancellation process

To avoid racing on the set and reset of interrupt_requested
This commit is contained in:
Jim Borden 2019-06-25 12:08:49 +01:00 committed by Andy Green
parent 1979bd8cc9
commit 477d50bf56
4 changed files with 15 additions and 7 deletions

View file

@ -289,6 +289,7 @@ struct lws_context_per_thread {
volatile struct lws_foreign_thread_pollfd * volatile foreign_pfd_list;
#ifdef _WIN32
WSAEVENT events;
CRITICAL_SECTION interrupt_lock;
#endif
lws_sockfd_type dummy_pipe_fds[2];
struct lws *pipe_wsi;
@ -345,7 +346,7 @@ struct lws_context_per_thread {
unsigned char event_loop_foreign:1;
unsigned char event_loop_destroy_processing_done:1;
#ifdef _WIN32
unsigned char interrupt_requested:1;
unsigned char interrupt_requested:1;
#endif
};

View file

@ -71,6 +71,7 @@ lws_plat_init(struct lws_context *context,
while (n--) {
pt->fds_count = 0;
pt->events = WSACreateEvent(); /* the cancel event */
InitializeCriticalSection(&pt->interrupt_lock);
pt++;
}
@ -93,6 +94,7 @@ lws_plat_context_early_destroy(struct lws_context *context)
while (n--) {
WSACloseEvent(pt->events);
DeleteCriticalSection(&pt->interrupt_lock);
pt++;
}
}

View file

@ -35,7 +35,9 @@ lws_plat_pipe_signal(struct lws *wsi)
{
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
pt->interrupt_requested = 1;
EnterCriticalSection(&pt->interrupt_lock);
pt->interrupt_requested = 1;
LeaveCriticalSection(&pt->interrupt_lock);
WSASetEvent(pt->events); /* trigger the cancel event */
return 0;

View file

@ -137,11 +137,14 @@ _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
ev = WSAWaitForMultipleEvents(1, &pt->events, FALSE, timeout_ms, FALSE);
if (ev == WSA_WAIT_EVENT_0) {
if(pt->interrupt_requested) {
pt->interrupt_requested = 0;
lws_broadcast(context, LWS_CALLBACK_EVENT_WAIT_CANCELLED, NULL, 0);
return 0;
}
EnterCriticalSection(&pt->interrupt_lock);
const int interrupt_requested = pt->interrupt_requested;
pt->interrupt_requested = 0;
LeaveCriticalSection(&pt->interrupt_lock);
if(interrupt_requested) {
lws_broadcast(context, LWS_CALLBACK_EVENT_WAIT_CANCELLED, NULL, 0);
return 0;
}
unsigned int eIdx;