mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
libuv: context creation fails via destroy
When using a foreign libuv loop, context creation may fail after adding handles to the foreign loop... if so, it can no longer deal with the fatal error by unpicking the created context and returning NULL... it has to brazen it out with a half-baked context that has already started the destroy flow and allow the foreign loop to close out the handles the usual way for libuv. https://github.com/warmcat/libwebsockets/issues/2129
This commit is contained in:
parent
8f68bc1fc8
commit
b3ddd3db17
1 changed files with 46 additions and 14 deletions
|
@ -401,6 +401,9 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
struct lws_plugin *evlib_plugin_list = NULL;
|
||||
char *ld_env;
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
char fatal_exit_defer = 0;
|
||||
#endif
|
||||
|
||||
if (lpf) {
|
||||
lpf+= 2;
|
||||
|
@ -526,6 +529,11 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
goto bail;
|
||||
}
|
||||
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
if (!n) /* libuv */
|
||||
fatal_exit_defer = !!info->foreign_loops;
|
||||
#endif
|
||||
|
||||
if (!evlib_plugin_list) {
|
||||
lwsl_err("%s: unable to load evlib plugin %s\n",
|
||||
__func__, map[n].name);
|
||||
|
@ -554,6 +562,7 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
if (lws_check_opt(info->options, LWS_SERVER_OPTION_LIBUV)) {
|
||||
extern const lws_plugin_evlib_t evlib_uv;
|
||||
plev = &evlib_uv;
|
||||
fatal_exit_defer = !!info->foreign_loops;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -766,7 +775,7 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
if (n == -1) {
|
||||
lwsl_err("Get RLIMIT_NOFILE failed!\n");
|
||||
|
||||
return NULL;
|
||||
goto free_context_fail;
|
||||
}
|
||||
context->max_fds = rt.rlim_cur;
|
||||
#else
|
||||
|
@ -790,7 +799,7 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
lwsl_err("%s: problem getting process max files\n",
|
||||
__func__);
|
||||
|
||||
return NULL;
|
||||
goto free_context_fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1023,13 +1032,19 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
context->fd_limit_per_thread;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Past here, we may have added handles to the event lib
|
||||
* loop and if libuv, have to take care about how to unpick them...
|
||||
*/
|
||||
|
||||
if (lws_plat_init(context, info))
|
||||
goto bail;
|
||||
goto bail_libuv_aware;
|
||||
|
||||
#if defined(LWS_WITH_NETWORK)
|
||||
if (context->event_loop_ops->init_context)
|
||||
if (context->event_loop_ops->init_context(context, info))
|
||||
goto bail;
|
||||
goto bail_libuv_aware;
|
||||
|
||||
|
||||
if (context->event_loop_ops->init_pt)
|
||||
|
@ -1040,11 +1055,11 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
lp = info->foreign_loops[n];
|
||||
|
||||
if (context->event_loop_ops->init_pt(context, lp, n))
|
||||
goto bail;
|
||||
goto bail_libuv_aware;
|
||||
}
|
||||
|
||||
if (lws_create_event_pipes(context))
|
||||
goto bail;
|
||||
goto bail_libuv_aware;
|
||||
|
||||
for (n = 0; n < context->count_threads; n++) {
|
||||
LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar) {
|
||||
|
@ -1126,18 +1141,18 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
if (!vh) {
|
||||
lwsl_err("%s: failed to create system vhost\n",
|
||||
__func__);
|
||||
goto bail;
|
||||
goto bail_libuv_aware;
|
||||
}
|
||||
|
||||
context->vhost_system = vh;
|
||||
|
||||
if (lws_protocol_init_vhost(vh, NULL)) {
|
||||
lwsl_err("%s: failed to init system vhost\n", __func__);
|
||||
goto bail;
|
||||
goto bail_libuv_aware;
|
||||
}
|
||||
#if defined(LWS_WITH_SYS_ASYNC_DNS)
|
||||
if (lws_async_dns_init(context))
|
||||
goto bail;
|
||||
goto bail_libuv_aware;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1198,17 +1213,17 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
LWS_SERVER_OPTION_EXPLICIT_VHOSTS));
|
||||
|
||||
if (lws_ss_policy_parse_begin(context, 0))
|
||||
goto bail;
|
||||
goto bail_libuv_aware;
|
||||
|
||||
n = lws_ss_policy_parse(context,
|
||||
(uint8_t *)context->pss_policies_json,
|
||||
strlen(context->pss_policies_json));
|
||||
if (n != LEJP_CONTINUE && n < 0)
|
||||
goto bail;
|
||||
goto bail_libuv_aware;
|
||||
|
||||
if (lws_ss_policy_set(context, "hardcoded")) {
|
||||
lwsl_err("%s: policy set failed\n", __func__);
|
||||
goto bail;
|
||||
goto bail_libuv_aware;
|
||||
}
|
||||
} else
|
||||
#else
|
||||
|
@ -1217,7 +1232,7 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
|
||||
if (lws_ss_policy_set(context, "hardcoded")) {
|
||||
lwsl_err("%s: policy set failed\n", __func__);
|
||||
goto bail;
|
||||
goto bail_libuv_aware;
|
||||
}
|
||||
} //else
|
||||
#endif
|
||||
|
@ -1236,7 +1251,7 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
*/
|
||||
if (!lws_check_opt(info->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS))
|
||||
if (lws_plat_drop_app_privileges(context, 1))
|
||||
goto bail;
|
||||
goto bail_libuv_aware;
|
||||
|
||||
#if defined(LWS_WITH_SYS_STATE)
|
||||
/*
|
||||
|
@ -1260,6 +1275,14 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
|
||||
#if defined(LWS_WITH_NETWORK)
|
||||
fail_clean_pipes:
|
||||
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
if (fatal_exit_defer) {
|
||||
lws_context_destroy(context);
|
||||
return context;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (n = 0; n < context->count_threads; n++)
|
||||
lws_destroy_event_pipe(context->pt[n].pipe_wsi);
|
||||
|
||||
|
@ -1275,9 +1298,18 @@ bail:
|
|||
|
||||
return NULL;
|
||||
|
||||
bail_libuv_aware:
|
||||
lws_context_destroy(context);
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
return fatal_exit_defer ? context : NULL;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
fail_event_libs:
|
||||
lwsl_err("Requested event library support not configured\n");
|
||||
|
||||
free_context_fail:
|
||||
lws_free(context);
|
||||
|
||||
return NULL;
|
||||
|
|
Loading…
Add table
Reference in a new issue