wsi->user_space, (void *)&pa, 1))
return -1;
+ /*
+ * detach ourselves from vh protocol list if we're on one
+ * A -> B -> C
+ * A -> C , or, B -> C, or A -> B
+ */
+ lwsl_info("%s: removing same prot wsi %p\n", __func__, wsi);
+ if (wsi->same_vh_protocol_prev) {
+ assert (*(wsi->same_vh_protocol_prev) == wsi);
+ lwsl_info("have prev %p, setting him to our next %p\n",
+ wsi->same_vh_protocol_prev,
+ wsi->same_vh_protocol_next);
+
+ /* guy who pointed to us should point to our next */
+ *(wsi->same_vh_protocol_prev) = wsi->same_vh_protocol_next;
+ } //else
+ //lwsl_err("null wsi->prev\n");
+ /* our next should point back to our prev */
+ if (wsi->same_vh_protocol_next) {
+ lwsl_info("have next %p\n");
+ wsi->same_vh_protocol_next->same_vh_protocol_prev =
+ wsi->same_vh_protocol_prev;
+ } //else
+ //lwsl_err("null wsi->next\n");
+
lws_libev_io(wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE | LWS_EV_PREPARE_DELETION);
lws_libuv_io(wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE | LWS_EV_PREPARE_DELETION);
if (wsi->state == LWSS_SHUTDOWN)
return 0;
+ if (wsi->socket_is_permanently_unusable)
+ return 0;
+
#ifdef LWS_USE_HTTP2
lwsl_info("%s: %p\n", __func__, wsi);
}
/**
- * lws_callback_on_writable_all_protocol() - Request a callback for
+ * lws_callback_on_writable_all_protocol_vhost() - Request a callback for
* all connections using the given protocol when it
* becomes possible to write to each socket without
* blocking in turn.
*
- * @context: lws_context
+ * This calls back connections with the same protocol ON THE SAME
+ * VHOST ONLY.
+ *
+ * @vhost: Only consider connections on this lws_vhost
* @protocol: Protocol whose connections will get callbacks
*/
LWS_VISIBLE int
-lws_callback_on_writable_all_protocol(const struct lws_context *context,
+lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost,
const struct lws_protocols *protocol)
{
- const struct lws_context_per_thread *pt = &context->pt[0];
- unsigned int n, m = context->count_threads;
struct lws *wsi;
- while (m--) {
- for (n = 0; n < pt->fds_count; n++) {
- wsi = wsi_from_fd(context, pt->fds[n].fd);
- if (!wsi)
- continue;
- if (wsi->protocol == protocol)
- lws_callback_on_writable(wsi);
+ if (protocol < vhost->protocols ||
+ protocol >= (vhost->protocols + vhost->count_protocols)) {
+ lwsl_err("%s: protocol is not from vhost\n", __func__);
+
+ return -1;
+ }
+
+ wsi = vhost->same_vh_protocol_list[protocol - vhost->protocols];
+ //lwsl_notice("%s: protocol %p, start wsi %p\n", __func__, protocol, wsi);
+ while (wsi) {
+ //lwsl_notice("%s: protocol %p, this wsi %p (wsi->protocol=%p)\n",
+ // __func__, protocol, wsi, wsi->protocol);
+ assert(wsi->protocol == protocol);
+ assert(*wsi->same_vh_protocol_prev == wsi);
+ if (wsi->same_vh_protocol_next) {
+ // lwsl_err("my next says %p\n", wsi->same_vh_protocol_next);
+ // lwsl_err("my next's prev says %p\n",
+ // wsi->same_vh_protocol_next->same_vh_protocol_prev);
+ assert(wsi->same_vh_protocol_next->same_vh_protocol_prev == &wsi->same_vh_protocol_next);
}
- pt++;
+ lws_callback_on_writable(wsi);
+ wsi = wsi->same_vh_protocol_next;
}
return 0;
}
-
/**
- * lws_callback_on_writable_all_protocol_vhost() - Request a callback for
+ * lws_callback_on_writable_all_protocol() - Request a callback for
* all connections using the given protocol when it
* becomes possible to write to each socket without
* blocking in turn.
*
- * @vhost: Only consider connections on this lws_vhost
+ * This calls back any connection using the same protocol on ANY
+ * VHOST.
+ *
+ * @context: lws_context
* @protocol: Protocol whose connections will get callbacks
*/
LWS_VISIBLE int
-lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost,
+lws_callback_on_writable_all_protocol(const struct lws_context *context,
const struct lws_protocols *protocol)
{
- const struct lws_context *context = vhost->context;
- const struct lws_context_per_thread *pt = &context->pt[0];
- unsigned int n, m = context->count_threads;
- struct lws *wsi;
-
- while (m--) {
- for (n = 0; n < pt->fds_count; n++) {
- wsi = wsi_from_fd(context, pt->fds[n].fd);
- if (!wsi)
- continue;
- if (wsi->vhost == vhost && wsi->protocol == protocol)
- lws_callback_on_writable(wsi);
- }
- pt++;
+ struct lws_vhost *vhost = context->vhost_list;
+ int n;
+
+ while (vhost) {
+ for (n = 0; n < vhost->count_protocols; n++)
+ if (protocol->callback ==
+ vhost->protocols[n].callback &&
+ !strcmp(protocol->name, vhost->protocols[n].name))
+ break;
+ if (n != vhost->count_protocols)
+ lws_callback_on_writable_all_protocol_vhost(
+ vhost, &vhost->protocols[n]);
+
+ vhost = vhost->vhost_next;
}
return 0;
hit = 0;
while (*p && !hit) {
- unsigned int n = 0;
+ n = 0;
while (n < sizeof(protocol_name) - 1 && *p && *p !=',')
protocol_name[n++] = *p++;
protocol_name[n] = '\0';
if (wsi->vhost->protocols[n].name &&
!strcmp(wsi->vhost->protocols[n].name,
protocol_name)) {
- lwsl_info("prot match %d\n", n);
wsi->protocol = &wsi->vhost->protocols[n];
hit = 1;
break;
}
/*
* some clients only have one protocol and
- * do not sent the protocol list header...
+ * do not send the protocol list header...
* allow it and match to protocol 0
*/
lwsl_info("defaulting to prot 0 handler\n");
+ n = 0;
wsi->protocol = &wsi->vhost->protocols[0];
}
* Give the user code a chance to study the request and
* have the opportunity to deny it
*/
-
if ((wsi->protocol->callback)(wsi,
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
wsi->user_space,
goto bail_nuke_ah;
}
+ /*
+ * stitch protocol choice into the vh protocol linked list
+ * We always insert ourselves at the start of the list
+ *
+ * X <-> B
+ * X <-> pAn <-> pB
+ */
+ //lwsl_err("%s: pre insert vhost start wsi %p, that wsi prev == %p\n",
+ // __func__,
+ // wsi->vhost->same_vh_protocol_list[n],
+ // wsi->same_vh_protocol_prev);
+ wsi->same_vh_protocol_prev = /* guy who points to us */
+ &wsi->vhost->same_vh_protocol_list[n];
+ wsi->same_vh_protocol_next = /* old first guy is our next */
+ wsi->vhost->same_vh_protocol_list[n];
+ /* we become the new first guy */
+ wsi->vhost->same_vh_protocol_list[n] = wsi;
+
+ if (wsi->same_vh_protocol_next)
+ /* old first guy points back to us now */
+ wsi->same_vh_protocol_next->same_vh_protocol_prev =
+ &wsi->same_vh_protocol_next;
+
+
+
/* we are upgrading to ws, so http/1.1 and keepalive +
* pipelined header considerations about keeping the ah around
* no longer apply. However it's common for the first ws