mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
context_destroy: figure out if anything still in event loop
This commit is contained in:
parent
bce8cca042
commit
9cce1874b0
3 changed files with 61 additions and 2 deletions
|
@ -1721,6 +1721,10 @@ lws_vhost_destroy(struct lws_vhost *vh)
|
|||
* destroys the context itself, setting what was info.pcontext to NULL.
|
||||
*/
|
||||
|
||||
/*
|
||||
* destroy the actual context itself
|
||||
*/
|
||||
|
||||
static void
|
||||
lws_context_destroy3(struct lws_context *context)
|
||||
{
|
||||
|
@ -1733,6 +1737,10 @@ lws_context_destroy3(struct lws_context *context)
|
|||
*pcontext_finalize = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* really start destroying things
|
||||
*/
|
||||
|
||||
void
|
||||
lws_context_destroy2(struct lws_context *context)
|
||||
{
|
||||
|
@ -1802,6 +1810,10 @@ lws_context_destroy2(struct lws_context *context)
|
|||
lws_context_destroy3(context);
|
||||
}
|
||||
|
||||
/*
|
||||
* Begin the context takedown
|
||||
*/
|
||||
|
||||
LWS_VISIBLE void
|
||||
lws_context_destroy(struct lws_context *context)
|
||||
{
|
||||
|
@ -1909,6 +1921,22 @@ lws_context_destroy(struct lws_context *context)
|
|||
|
||||
lws_plat_context_early_destroy(context);
|
||||
|
||||
/*
|
||||
* We face two different needs depending if foreign loop or not.
|
||||
*
|
||||
* 1) If foreign loop, we really want to advance the destroy_context()
|
||||
* past here, and block only for libuv-style async close completion.
|
||||
*
|
||||
* 2a) If poll, and we exited by ourselves and are calling a final
|
||||
* destroy_context() outside of any service already, we want to
|
||||
* advance all the way in one step.
|
||||
*
|
||||
* 2b) If poll, and we are reacting to a SIGINT, service thread(s) may
|
||||
* be in poll wait or servicing. We can't advance the
|
||||
* destroy_context() to the point it's freeing things; we have to
|
||||
* leave that for the final destroy_context() after the service
|
||||
* thread(s) are finished calling for service.
|
||||
*/
|
||||
|
||||
if (context->event_loop_ops->destroy_context1) {
|
||||
context->event_loop_ops->destroy_context1(context);
|
||||
|
@ -1916,5 +1944,10 @@ lws_context_destroy(struct lws_context *context)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!context->pt[0].event_loop_foreign)
|
||||
for (n = 0; n < context->count_threads; n++)
|
||||
if (context->pt[n].inside_service)
|
||||
return;
|
||||
|
||||
lws_context_destroy2(context);
|
||||
}
|
||||
|
|
|
@ -593,6 +593,7 @@ struct lws_context_per_thread {
|
|||
unsigned char tid;
|
||||
|
||||
unsigned char lock_depth;
|
||||
unsigned char inside_service:1;
|
||||
unsigned char event_loop_foreign:1;
|
||||
unsigned char event_loop_destroy_processing_done:1;
|
||||
};
|
||||
|
|
|
@ -939,24 +939,49 @@ lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd)
|
|||
LWS_VISIBLE int
|
||||
lws_service(struct lws_context *context, int timeout_ms)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &context->pt[0];
|
||||
int n;
|
||||
|
||||
if (!context)
|
||||
return 1;
|
||||
|
||||
pt->inside_service = 1;
|
||||
|
||||
if (context->event_loop_ops->run_pt) {
|
||||
/* we are configured for an event loop */
|
||||
context->event_loop_ops->run_pt(context, 0);
|
||||
|
||||
pt->inside_service = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
return lws_plat_service(context, timeout_ms);
|
||||
n = lws_plat_service(context, timeout_ms);
|
||||
|
||||
pt->inside_service = 0;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
LWS_VISIBLE int
|
||||
lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &context->pt[tsi];
|
||||
int n;
|
||||
|
||||
pt->inside_service = 1;
|
||||
|
||||
if (context->event_loop_ops->run_pt) {
|
||||
/* we are configured for an event loop */
|
||||
context->event_loop_ops->run_pt(context, tsi);
|
||||
|
||||
pt->inside_service = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return _lws_plat_service_tsi(context, timeout_ms, tsi);
|
||||
n = _lws_plat_service_tsi(context, timeout_ms, tsi);
|
||||
|
||||
pt->inside_service = 0;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue