mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
extensions change child count to highest child subchannel
This also changes the wsi_children array to be indexed by subchannel - 2, non-existent channels are NULL in there and highest_child_subchannel is a highwater mark for the highest subchannel ever used. That way we can immediately get the wsi for a subchannel at the cost of some extra sparse skipping during management. This also takes care of scanning for empty slots on allocation and NULLing on close of subchannel instead of deletion. Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
parent
f6652412f3
commit
8c6aaa2b43
2 changed files with 53 additions and 31 deletions
|
@ -431,8 +431,8 @@ bail2:
|
|||
|
||||
|
||||
conn->wsi_children[conn->block_subchannel - MUX_REAL_CHILD_INDEX_OFFSET] = wsi_child;
|
||||
if (conn->count_children <= conn->block_subchannel - MUX_REAL_CHILD_INDEX_OFFSET)
|
||||
conn->count_children = conn->block_subchannel - MUX_REAL_CHILD_INDEX_OFFSET + 1;
|
||||
if (conn->highest_child_subchannel <= conn->block_subchannel - MUX_REAL_CHILD_INDEX_OFFSET)
|
||||
conn->highest_child_subchannel = conn->block_subchannel - MUX_REAL_CHILD_INDEX_OFFSET + 1;
|
||||
|
||||
|
||||
/* notify user code that we're ready to roll */
|
||||
|
@ -481,7 +481,7 @@ bail2:
|
|||
* to tell us when it ate a full frame, so we watch its state
|
||||
* afterwards
|
||||
*/
|
||||
if (conn->block_subchannel - MUX_REAL_CHILD_INDEX_OFFSET > conn->count_children) {
|
||||
if (conn->block_subchannel - MUX_REAL_CHILD_INDEX_OFFSET >= conn->highest_child_subchannel) {
|
||||
fprintf(stderr, "Illegal subchannel\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -547,6 +547,7 @@ int lws_extension_callback_x_google_mux(
|
|||
struct lws_ext_x_google_mux_context *mux_ctx =
|
||||
ext->per_context_private_data;
|
||||
struct libwebsocket *wsi_parent;
|
||||
struct libwebsocket *wsi_child;
|
||||
struct libwebsocket *wsi_temp;
|
||||
unsigned char *pin = (unsigned char *)in;
|
||||
unsigned char *basepin;
|
||||
|
@ -658,10 +659,12 @@ int lws_extension_callback_x_google_mux(
|
|||
continue;
|
||||
}
|
||||
|
||||
if (parent_conn->count_children >=
|
||||
if (parent_conn->highest_child_subchannel >=
|
||||
sizeof(parent_conn->wsi_children) /
|
||||
sizeof(parent_conn->wsi_children[0]))
|
||||
sizeof(parent_conn->wsi_children[0])) {
|
||||
fprintf(stderr, "Can't add any more children\n");
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* this established connection will do, bind them
|
||||
* from now on child will only operate through parent
|
||||
|
@ -721,14 +724,9 @@ int lws_extension_callback_x_google_mux(
|
|||
fprintf(stderr, "failed to get parent conn\n");
|
||||
break;
|
||||
}
|
||||
for (n = 0; n < parent_conn->count_children; n++)
|
||||
if (parent_conn->wsi_children[n] == wsi) {
|
||||
parent_conn->count_children--;
|
||||
while (n < parent_conn->count_children) {
|
||||
parent_conn->wsi_children[n] = parent_conn->wsi_children[n + 1];
|
||||
n++;
|
||||
}
|
||||
}
|
||||
for (n = 0; n < parent_conn->highest_child_subchannel; n++)
|
||||
if (parent_conn->wsi_children[n] == wsi)
|
||||
parent_conn->wsi_children[n] = NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -777,12 +775,12 @@ handle_additions:
|
|||
* them all go it alone
|
||||
*/
|
||||
|
||||
wsi_parent = wsi->candidate_children_list;
|
||||
while (wsi_parent) {
|
||||
wsi_temp = wsi_parent->candidate_children_list;
|
||||
wsi_child = wsi->candidate_children_list;
|
||||
while (wsi_child) {
|
||||
wsi_temp = wsi_child->candidate_children_list;
|
||||
/* let them each connect privately then */
|
||||
__libwebsocket_client_connect_2(context, wsi_parent);
|
||||
wsi_parent = wsi_temp;
|
||||
__libwebsocket_client_connect_2(context, wsi_child);
|
||||
wsi_child = wsi_temp;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -794,23 +792,43 @@ handle_additions:
|
|||
* as mux subchannel real children
|
||||
*/
|
||||
|
||||
wsi_parent = wsi->candidate_children_list;
|
||||
while (wsi_parent) {
|
||||
wsi_child = wsi->candidate_children_list;
|
||||
n = 0;
|
||||
while (wsi_child) {
|
||||
|
||||
wsi_temp = wsi_child->candidate_children_list;
|
||||
|
||||
/* find an empty subchannel */
|
||||
|
||||
while ((n < (sizeof(conn->wsi_children) / sizeof(conn->wsi_children[0]))) &&
|
||||
conn->wsi_children[n] != NULL)
|
||||
n++;
|
||||
|
||||
if (n >= (sizeof(conn->wsi_children) / sizeof(conn->wsi_children[0]))) {
|
||||
/* no room at the inn */
|
||||
|
||||
/* let them each connect privately then */
|
||||
__libwebsocket_client_connect_2(context, wsi_child);
|
||||
wsi_child = wsi_temp;
|
||||
continue;
|
||||
}
|
||||
|
||||
muxdebug(" using mux addchannel action for candidate child\n");
|
||||
|
||||
wsi_temp = wsi_parent->candidate_children_list;
|
||||
/* let them each connect privately then */
|
||||
/* pile the children on the parent */
|
||||
lws_ext_x_google_mux__send_addchannel(context, wsi,
|
||||
conn, wsi_parent,
|
||||
conn->count_children + MUX_REAL_CHILD_INDEX_OFFSET, wsi->c_path);
|
||||
conn, wsi_child,
|
||||
n + MUX_REAL_CHILD_INDEX_OFFSET, wsi->c_path);
|
||||
|
||||
conn->sticky_mux_used = 1;
|
||||
|
||||
conn->wsi_children[conn->count_children++] = wsi_parent;
|
||||
conn->wsi_children[n] = wsi_child;
|
||||
if ((n + 1) > conn->highest_child_subchannel)
|
||||
conn->highest_child_subchannel = n + 1;
|
||||
|
||||
muxdebug("Setting CHILD LIST entry %d to %p\n",
|
||||
conn->count_children - 1, (void *)wsi_parent);
|
||||
wsi_parent = wsi_temp;
|
||||
n + MUX_REAL_CHILD_INDEX_OFFSET, (void *)wsi_parent);
|
||||
wsi_child = wsi_temp;
|
||||
}
|
||||
wsi->candidate_children_list = NULL;
|
||||
return 1;
|
||||
|
@ -910,8 +928,9 @@ handle_additions:
|
|||
* if we have children, service their timeouts using the same
|
||||
* handler as toplevel guys to allow recursion
|
||||
*/
|
||||
for (n = 0; n < conn->count_children; n++)
|
||||
libwebsocket_service_timeout_check(context,
|
||||
for (n = 0; n < conn->highest_child_subchannel; n++)
|
||||
if (conn->wsi_children[n])
|
||||
libwebsocket_service_timeout_check(context,
|
||||
conn->wsi_children[n], len);
|
||||
break;
|
||||
|
||||
|
@ -983,7 +1002,10 @@ handle_additions:
|
|||
return 0;
|
||||
}
|
||||
|
||||
for (n = 0; n < conn->count_children; n++) {
|
||||
for (n = 0; n < conn->highest_child_subchannel; n++) {
|
||||
|
||||
if (!conn->wsi_children[n])
|
||||
continue;
|
||||
|
||||
child_conn = NULL;
|
||||
for (m = 0; m < conn->wsi_children[n]->count_active_extensions; m++)
|
||||
|
|
|
@ -79,7 +79,7 @@ struct lws_ext_x_google_mux_conn {
|
|||
struct libwebsocket *wsi_parent;
|
||||
int subchannel;
|
||||
struct libwebsocket *wsi_children[MAX_CLIENTS];
|
||||
int count_children;
|
||||
int highest_child_subchannel;
|
||||
char awaiting_POLLOUT;
|
||||
int count_children_needing_POLLOUT;
|
||||
int sticky_mux_used;
|
||||
|
|
Loading…
Add table
Reference in a new issue