@@ -1455,76 +1455,64 @@ void lws_wsi_mux_insert(struct lws *wsi, struct lws *parent_wsi,
14551455 }
14561456#endif
14571457
1458- /* new guy's sibling is whoever was the first child before */
1459- wsi -> mux .sibling_list = parent_wsi -> mux .child_list ;
1460-
1461- /* first child is now the new guy */
1462- parent_wsi -> mux .child_list = wsi ;
1463-
1464- parent_wsi -> mux .child_count ++ ;
1458+ /* new guy becomes the head child of the parent's mux child list */
1459+ lws_dll2_add_head (& wsi -> mux .sibling_list , & parent_wsi -> mux .child_list_owner );
14651460}
14661461
14671462struct lws * lws_wsi_mux_from_id (struct lws * parent_wsi , unsigned int sid ) {
1468- lws_start_foreach_ll (struct lws * , wsi , parent_wsi -> mux .child_list ) {
1469- if (wsi -> mux .my_sid == sid )
1463+ lws_start_foreach_dll (struct lws_dll2 * , d , parent_wsi -> mux .child_list_owner .head ) {
1464+ struct lws * wsi = lws_container_of (d , struct lws , mux .sibling_list );
1465+ if ((unsigned int )wsi -> mux .my_sid == sid )
14701466 return wsi ;
14711467 }
1472- lws_end_foreach_ll ( wsi , mux . sibling_list );
1468+ lws_end_foreach_dll ( d );
14731469
14741470 return NULL ;
14751471}
14761472
14771473void lws_wsi_mux_dump_children (struct lws * wsi ) {
14781474#if defined(_DEBUG )
1475+ struct lws * parent ;
1476+
14791477 if (!wsi -> mux .parent_wsi || !lwsl_visible (LLL_INFO ))
14801478 return ;
14811479
1482- lws_start_foreach_llp (struct lws * * , w , wsi -> mux .parent_wsi -> mux .child_list ) {
1480+ parent = wsi -> mux .parent_wsi ;
1481+
1482+ lws_start_foreach_dll (struct lws_dll2 * , d , parent -> mux .child_list_owner .head ) {
1483+ struct lws * w = lws_container_of (d , struct lws , mux .sibling_list );
14831484 lwsl_wsi_info (wsi , " \\---- child %s %s\n" ,
1484- (* w )-> role_ops ? (* w )-> role_ops -> name : "?" , lws_wsi_tag (* w ));
1485- assert (* w != (* w )-> mux .sibling_list );
1485+ w -> role_ops ? w -> role_ops -> name : "?" , lws_wsi_tag (w ));
14861486 }
1487- lws_end_foreach_llp ( w , mux . sibling_list );
1487+ lws_end_foreach_dll ( d );
14881488#endif
14891489}
14901490
14911491void lws_wsi_mux_close_children (struct lws * wsi , int reason ) {
1492- struct lws * wsi2 ;
1493- struct lws * * w ;
14941492
1495- if (!wsi -> mux .child_list )
1493+ if (!wsi -> mux .child_list_owner . head )
14961494 return ;
14971495
1498- w = & wsi -> mux .child_list ;
1499- while (* w ) {
1500- lwsl_wsi_info ((* w ), " closing child" );
1501- /* disconnect from siblings */
1502- wsi2 = (* w )-> mux .sibling_list ;
1503- assert (wsi2 != * w );
1504- (* w )-> mux .sibling_list = NULL ;
1505- (* w )-> socket_is_permanently_unusable = 1 ;
1506- __lws_close_free_wsi (* w , (enum lws_close_status )reason ,
1496+ lws_start_foreach_dll_safe (struct lws_dll2 * , d , d1 ,
1497+ wsi -> mux .child_list_owner .head ) {
1498+ struct lws * w = lws_container_of (d , struct lws , mux .sibling_list );
1499+
1500+ lwsl_wsi_info (w , " closing child" );
1501+ w -> socket_is_permanently_unusable = 1 ;
1502+ __lws_close_free_wsi (w , (enum lws_close_status )reason ,
15071503 "mux child recurse" );
1508- * w = wsi2 ;
15091504 }
1505+ lws_end_foreach_dll_safe (d , d1 );
15101506}
15111507
15121508void lws_wsi_mux_sibling_disconnect (struct lws * wsi ) {
1513- struct lws * wsi2 ;
15141509
1515- lws_start_foreach_llp (struct lws * * , w , wsi -> mux .parent_wsi -> mux .child_list ) {
1510+ if (!wsi -> mux .parent_wsi )
1511+ return ;
15161512
1517- /* disconnect from siblings */
1518- if (* w == wsi ) {
1519- wsi2 = (* w )-> mux .sibling_list ;
1520- (* w )-> mux .sibling_list = NULL ;
1521- * w = wsi2 ;
1522- lwsl_wsi_debug (wsi , " disentangled from sibling %s" , lws_wsi_tag (wsi2 ));
1523- break ;
1524- }
1525- }
1526- lws_end_foreach_llp (w , mux .sibling_list );
1527- wsi -> mux .parent_wsi -> mux .child_count -- ;
1513+ lws_dll2_remove (& wsi -> mux .sibling_list );
1514+ lwsl_wsi_debug (wsi , " disentangled from mux parent %s" ,
1515+ lws_wsi_tag (wsi -> mux .parent_wsi ));
15281516
15291517 wsi -> mux .parent_wsi = NULL ;
15301518}
@@ -1534,16 +1522,15 @@ void lws_wsi_mux_dump_waiting_children(struct lws *wsi) {
15341522 lwsl_info ("%s: %s: children waiting for POLLOUT service:\n" , __func__ ,
15351523 lws_wsi_tag (wsi ));
15361524
1537- wsi = wsi -> mux .child_list ;
1538- while (wsi ) {
1539- lwsl_wsi_info (wsi , " %c sid %llu: 0x%x %s %s" ,
1540- wsi -> mux .requested_POLLOUT ? '*' : ' ' ,
1541- (unsigned long long )wsi -> mux .my_sid ,
1542- lwsi_state (wsi ), wsi -> role_ops -> name ,
1543- wsi -> a .protocol ? wsi -> a .protocol -> name : "noprotocol" );
1544-
1545- wsi = wsi -> mux .sibling_list ;
1525+ lws_start_foreach_dll (struct lws_dll2 * , d , wsi -> mux .child_list_owner .head ) {
1526+ struct lws * w = lws_container_of (d , struct lws , mux .sibling_list );
1527+ lwsl_wsi_info (w , " %c sid %llu: 0x%x %s %s" ,
1528+ w -> mux .requested_POLLOUT ? '*' : ' ' ,
1529+ (unsigned long long )w -> mux .my_sid ,
1530+ lwsi_state (w ), w -> role_ops -> name ,
1531+ w -> a .protocol ? w -> a .protocol -> name : "noprotocol" );
15461532 }
1533+ lws_end_foreach_dll (d );
15471534#endif
15481535}
15491536
@@ -1564,43 +1551,33 @@ int lws_wsi_mux_mark_parents_needing_writeable(struct lws *wsi) {
15641551 return 0 ; // already;
15651552}
15661553
1567- struct lws * lws_wsi_mux_move_child_to_tail (struct lws * * wsi2 ) {
1568- struct lws * w = * wsi2 ;
1569-
1570- while (w ) {
1571- if (!w -> mux .sibling_list ) { /* w is the current last */
1572- lwsl_wsi_debug (w , "*wsi2 = %s\n" , lws_wsi_tag (* wsi2 ));
1573-
1574- if (w == * wsi2 ) /* we are already last */
1575- break ;
1576-
1577- /* last points to us as new last */
1578- w -> mux .sibling_list = * wsi2 ;
1554+ /*
1555+ * Move the head mux child of parent_wsi to the tail of its sibling list, and
1556+ * clear its requested_POLLOUT. Returns the moved child (formerly the head),
1557+ * or NULL if there are no children. This implements the fair-share rotation
1558+ * used by the POLLOUT service loops.
1559+ */
1560+ struct lws * lws_wsi_mux_move_child_to_tail (struct lws * parent_wsi ) {
1561+ struct lws_dll2 * head ;
1562+ struct lws * w ;
15791563
1580- /* guy pointing to us until now points to
1581- * our old next */
1582- * wsi2 = ( * wsi2 ) -> mux . sibling_list ;
1564+ head = lws_dll2_get_head ( & parent_wsi -> mux . child_list_owner );
1565+ if (! head )
1566+ return NULL ;
15831567
1584- /* we point to nothing because we are last */
1585- w -> mux .sibling_list -> mux .sibling_list = NULL ;
1568+ w = lws_container_of (head , struct lws , mux .sibling_list );
15861569
1587- /* w becomes us */
1588- w = w -> mux .sibling_list ;
1589- break ;
1590- }
1591- w = w -> mux .sibling_list ;
1592- }
1570+ lws_dll2_remove (& w -> mux .sibling_list );
1571+ lws_dll2_add_tail (& w -> mux .sibling_list ,
1572+ & parent_wsi -> mux .child_list_owner );
15931573
15941574 /* clear the waiting for POLLOUT on the guy that was chosen */
1595-
1596- if (w )
1597- w -> mux .requested_POLLOUT = 0 ;
1575+ w -> mux .requested_POLLOUT = 0 ;
15981576
15991577 return w ;
16001578}
16011579
16021580int lws_wsi_mux_action_pending_writeable_reqs (struct lws * wsi ) {
1603- struct lws * w = wsi -> mux .child_list ;
16041581 struct lws * nwsi = lws_get_network_wsi (wsi );
16051582
16061583 if (wsi -> mux .requested_POLLOUT ) {
@@ -1609,14 +1586,16 @@ int lws_wsi_mux_action_pending_writeable_reqs(struct lws *wsi) {
16091586 return 0 ;
16101587 }
16111588
1612- while (w ) {
1589+ lws_start_foreach_dll (struct lws_dll2 * , d , wsi -> mux .child_list_owner .head ) {
1590+ struct lws * w = lws_container_of (d , struct lws , mux .sibling_list );
1591+
16131592 if (w -> mux .requested_POLLOUT ) {
16141593 if (lws_change_pollfd (nwsi , 0 , LWS_POLLOUT ))
16151594 return -1 ;
16161595 return 0 ;
16171596 }
1618- w = w -> mux .sibling_list ;
16191597 }
1598+ lws_end_foreach_dll (d );
16201599
16211600 if (lws_change_pollfd (nwsi , LWS_POLLOUT , 0 ))
16221601 return -1 ;
0 commit comments