lws_remove_from_timeout_list(wsi);
}
+static void
+lws_remove_child_from_any_parent(struct lws *wsi)
+{
+ struct lws **pwsi;
+
+ if (wsi->parent) {
+ /* detach ourselves from parent's child list */
+ pwsi = &wsi->parent->child_list;
+ while (*pwsi) {
+ if (*pwsi == wsi) {
+ //lwsl_notice("%s: detach %p from parent %p\n",
+ // __func__, wsi, wsi->parent);
+ *pwsi = wsi->sibling_list;
+ break;
+ }
+ pwsi = &(*pwsi)->sibling_list;
+ }
+ if (*pwsi)
+ lwsl_err("%s: failed to detach from parent\n",
+ __func__);
+ }
+}
+
void
lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason)
{
struct lws_context_per_thread *pt;
- struct lws **pwsi, *wsi1, *wsi2;
+ struct lws *wsi1, *wsi2;
struct lws_context *context;
struct lws_tokens eff_buf;
int n, m, ret;
if (!wsi)
return;
- if (wsi->mode == LWSCM_RAW_FILEDESC) {
- remove_wsi_socket_from_fds(wsi);
- wsi->protocol->callback(wsi,
- LWS_CALLBACK_RAW_CLOSE_FILE, wsi->user_space, NULL, 0);
- lws_free_wsi(wsi);
-
- return;
- }
-
lws_access_log(wsi);
#if defined(LWS_WITH_ESP8266)
if (wsi->premature_rx)
wsi->child_list = NULL;
}
+ if (wsi->mode == LWSCM_RAW_FILEDESC) {
+ lws_remove_child_from_any_parent(wsi);
+ remove_wsi_socket_from_fds(wsi);
+ wsi->protocol->callback(wsi,
+ LWS_CALLBACK_RAW_CLOSE_FILE,
+ wsi->user_space, NULL, 0);
+ lws_free_wsi(wsi);
+
+ return;
+ }
+
#ifdef LWS_WITH_CGI
if (wsi->mode == LWSCM_CGI) {
/* we are not a network connection, but a handler for CGI io */
just_kill_connection:
- if (wsi->parent) {
- /* detach ourselves from parent's child list */
- pwsi = &wsi->parent->child_list;
- while (*pwsi) {
- if (*pwsi == wsi) {
- //lwsl_notice("%s: detach %p from parent %p\n",
- // __func__, wsi, wsi->parent);
- *pwsi = wsi->sibling_list;
- break;
- }
- pwsi = &(*pwsi)->sibling_list;
- }
- if (*pwsi)
- lwsl_err("%s: failed to detach from parent\n",
- __func__);
- }
+ lws_remove_child_from_any_parent(wsi);
+
#if 0
/* manage the vhost same protocol list entry */
lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd);
typedef enum {
- LWS_ADOPT_HTTP = 1, /* absent implies RAW */
- LWS_ADOPT_SOCKET = 2, /* absent implies file descriptor */
- LWS_ADOPT_ALLOW_SSL = 4 /* if set requires LWS_ADOPT_SOCKET */
+ LWS_ADOPT_RAW_FILE_DESC = 0, /* convenience constant */
+ LWS_ADOPT_HTTP = 1, /* flag: absent implies RAW */
+ LWS_ADOPT_SOCKET = 2, /* flag: absent implies file descr */
+ LWS_ADOPT_ALLOW_SSL = 4 /* flag: if set requires LWS_ADOPT_SOCKET */
} lws_adoption_type;
typedef union {
* \param type: OR-ed combinations of lws_adoption_type flags
* \param fd: union with either .sockfd or .filefd set
* \param vh_prot_name: NULL or vh protocol name to bind raw connection to
+* \param parent: NULL or struct lws to attach new_wsi to as a child
*
* Either returns new wsi bound to accept_fd, or closes accept_fd and
* returns NULL, having cleaned up any new wsi pieces.
*
* If LWS_ADOPT_SOCKET is set, LWS adopts the socket in http serving mode, it's
* ready to accept an upgrade to ws or just serve http.
+*
+* parent may be NULL, if given it should be an existing wsi that will become the
+* parent of the new wsi created by this call.
*/
LWS_VISIBLE struct lws *
lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type,
- lws_sock_file_fd_type fd, const char *vh_prot_name);
-
+ lws_sock_file_fd_type fd, const char *vh_prot_name,
+ struct lws *parent);
/**
* lws_adopt_socket_readbuf() - adopt foreign socket and first rx as if listen socket accepted it
LWS_VISIBLE struct lws *
lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type,
- lws_sock_file_fd_type fd, const char *vh_prot_name)
+ lws_sock_file_fd_type fd, const char *vh_prot_name,
+ struct lws *parent)
{
struct lws_context *context = vh->context;
struct lws *new_wsi = lws_create_new_server_wsi(vh);
return NULL;
}
+ if (parent) {
+ new_wsi->parent = parent;
+ new_wsi->sibling_list = parent->child_list;
+ parent->child_list = new_wsi;
+ }
+
new_wsi->desc = fd;
- new_wsi->protocol = &context->vhost_list->
- protocols[vh->default_protocol_index];
- if (!(type & LWS_ADOPT_SOCKET)) {
+ if (vh_prot_name) {
new_wsi->protocol = lws_vhost_name_to_protocol(new_wsi->vhost,
- vh_prot_name);
+ vh_prot_name);
if (!new_wsi->protocol) {
lwsl_err("Protocol %s not enabled on vhost %s\n",
vh_prot_name, new_wsi->vhost->name);
- lws_free(new_wsi);
-
- return NULL;
+ goto bail;
}
- }
- if (type & LWS_ADOPT_SOCKET) {
+ if (lws_ensure_user_space(new_wsi))
+ goto bail;
+ } else
+ new_wsi->protocol = &context->vhost_list->
+ protocols[vh->default_protocol_index];
+ if (type & LWS_ADOPT_SOCKET) { /* socket desc */
lwsl_debug("%s: new wsi %p, sockfd %d\n", __func__, new_wsi,
(int)(size_t)fd.sockfd);
-
/* the transport is accepted... give him time to negotiate */
lws_set_timeout(new_wsi, PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,
context->timeout_secs);
esp8266_tcp_stream_accept(accept_fd, new_wsi);
#endif
#endif
- } else //* file desc */
+ } else /* file desc */
lwsl_debug("%s: new wsi %p, filefd %d\n", __func__, new_wsi,
(int)(size_t)fd.filefd);
lws_set_timeout(new_wsi, NO_PENDING_TIMEOUT, 0);
compatible_close(new_wsi->desc.sockfd);
}
- lws_free(new_wsi);
- return NULL;
+ goto bail;
}
if (!LWS_SSL_ENABLED(new_wsi->vhost) || !(type & LWS_ADOPT_ALLOW_SSL) ||
lws_close_free_wsi(new_wsi, LWS_CLOSE_STATUS_NOSTATUS);
return NULL;
+
+bail:
+ if (parent)
+ parent->child_list = new_wsi->sibling_list;
+ if (new_wsi->user_space)
+ lws_free(new_wsi->user_space);
+ lws_free(new_wsi);
+
+ return NULL;
}
LWS_VISIBLE struct lws *
fd.sockfd = accept_fd;
return lws_adopt_descriptor_vhost(vh, LWS_ADOPT_SOCKET |
- LWS_ADOPT_HTTP | LWS_ADOPT_ALLOW_SSL, fd, NULL);
+ LWS_ADOPT_HTTP | LWS_ADOPT_ALLOW_SSL, fd, NULL, NULL);
}
LWS_VISIBLE struct lws *
}
lwsl_notice("FIFO %s created\n", vhd->fifo_path);
u.filefd = vhd->fifo;
- if (!lws_adopt_descriptor_vhost(vhd->vhost, 0, u, "protocol-lws-raw-test")) {
+ if (!lws_adopt_descriptor_vhost(vhd->vhost, 0, u, "protocol-lws-raw-test", NULL)) {
lwsl_err("Failed to adopt fifo descriptor\n");
close(vhd->fifo);
unlink(vhd->fifo_path);
}
lwsl_notice("FIFO %s reopened\n", vhd->fifo_path);
u.filefd = vhd->fifo;
- if (!lws_adopt_descriptor_vhost(vhd->vhost, 0, u, "protocol-lws-raw-test")) {
+ if (!lws_adopt_descriptor_vhost(vhd->vhost, 0, u, "protocol-lws-raw-test", NULL)) {
lwsl_err("Failed to adopt fifo descriptor\n");
close(vhd->fifo);
return 1;