@@ -260,7 +260,9 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded)
260
260
#endif
261
261
262
262
topology = (mongoc_topology_t * ) bson_malloc0 (sizeof * topology );
263
- topology -> session_pool = NULL ;
263
+ topology -> session_pool =
264
+ mongoc_ts_pool_new (sizeof (mongoc_server_session_t ),
265
+ (void (* ) (void * )) _mongoc_server_session_dtor );
264
266
heartbeat_default =
265
267
single_threaded ? MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_SINGLE_THREADED
266
268
: MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_MULTI_THREADED ;
@@ -569,47 +571,14 @@ mongoc_topology_destroy (mongoc_topology_t *topology)
569
571
mongoc_uri_destroy (topology -> uri );
570
572
mongoc_topology_description_destroy (& topology -> description );
571
573
mongoc_topology_scanner_destroy (topology -> scanner );
572
-
573
- /* If we are single-threaded, the client will try to call
574
- _mongoc_topology_end_sessions_cmd when it dies. This removes
575
- sessions from the pool as it calls endSessions on them. In
576
- case this does not succeed, we clear the pool again here. */
577
- _mongoc_topology_clear_session_pool (topology );
574
+ mongoc_ts_pool_free (topology -> session_pool );
578
575
579
576
mongoc_cond_destroy (& topology -> cond_client );
580
577
bson_mutex_destroy (& topology -> mutex );
581
578
582
579
bson_free (topology );
583
580
}
584
581
585
- /*
586
- *--------------------------------------------------------------------------
587
- *
588
- * _mongoc_topology_clear_session_pool --
589
- *
590
- * Clears the pool of server sessions without sending endSessions.
591
- *
592
- * Returns:
593
- * Nothing.
594
- *
595
- * Side effects:
596
- * Server session pool will be emptied.
597
- *
598
- *--------------------------------------------------------------------------
599
- */
600
-
601
- void
602
- _mongoc_topology_clear_session_pool (mongoc_topology_t * topology )
603
- {
604
- mongoc_server_session_t * ss , * tmp1 , * tmp2 ;
605
-
606
- CDL_FOREACH_SAFE (topology -> session_pool , ss , tmp1 , tmp2 )
607
- {
608
- _mongoc_server_session_destroy (ss );
609
- }
610
- topology -> session_pool = NULL ;
611
- }
612
-
613
582
/* Returns false if none of the hosts were valid. */
614
583
bool
615
584
mongoc_topology_apply_scanned_srv_hosts (mongoc_uri_t * uri ,
@@ -1570,45 +1539,49 @@ _mongoc_topology_pop_server_session (mongoc_topology_t *topology,
1570
1539
bson_mutex_unlock (& topology -> mutex );
1571
1540
if (!mongoc_topology_select_server_id (
1572
1541
topology , MONGOC_SS_READ , NULL , error )) {
1573
- RETURN (NULL );
1542
+ ss = NULL ;
1543
+ goto done ;
1574
1544
}
1575
1545
1576
1546
bson_mutex_lock (& topology -> mutex );
1577
1547
timeout = td -> session_timeout_minutes ;
1578
1548
}
1579
1549
1580
1550
if (timeout == MONGOC_NO_SESSIONS ) {
1581
- bson_mutex_unlock (& topology -> mutex );
1582
1551
bson_set_error (error ,
1583
1552
MONGOC_ERROR_CLIENT ,
1584
1553
MONGOC_ERROR_CLIENT_SESSION_FAILURE ,
1585
1554
"Server does not support sessions" );
1586
- RETURN (NULL );
1555
+ ss = NULL ;
1556
+ bson_mutex_unlock (& topology -> mutex );
1557
+ goto done ;
1587
1558
}
1588
1559
}
1560
+ bson_mutex_unlock (& topology -> mutex );
1589
1561
1590
- while (topology -> session_pool ) {
1591
- ss = topology -> session_pool ;
1592
- CDL_DELETE (topology -> session_pool , ss );
1593
- /* Sessions do not expire when the topology type is load balanced. */
1594
- if (loadbalanced ) {
1562
+ while (true) {
1563
+ bool got_session ;
1564
+ ss = mongoc_ts_pool_try_pop (topology -> session_pool , & got_session );
1565
+ if (!got_session ) {
1566
+ /* The pool is empty */
1567
+ ss = mongoc_ts_pool_alloc_item (topology -> session_pool );
1568
+ if (!_mongoc_server_session_init (ss , error )) {
1569
+ mongoc_ts_pool_free_item (topology -> session_pool , ss );
1570
+ ss = NULL ;
1571
+ goto done ;
1572
+ }
1595
1573
break ;
1596
1574
}
1597
1575
1598
1576
if (_mongoc_server_session_timed_out (ss , timeout )) {
1599
- _mongoc_server_session_destroy ( ss );
1577
+ mongoc_ts_pool_free_item ( topology -> session_pool , ss );
1600
1578
ss = NULL ;
1601
- } else {
1602
- break ;
1579
+ continue ;
1603
1580
}
1581
+ break ;
1604
1582
}
1605
1583
1606
- bson_mutex_unlock (& topology -> mutex );
1607
-
1608
- if (!ss ) {
1609
- ss = _mongoc_server_session_new (error );
1610
- }
1611
-
1584
+ done :
1612
1585
RETURN (ss );
1613
1586
}
1614
1587
@@ -1633,46 +1606,25 @@ _mongoc_topology_push_server_session (mongoc_topology_t *topology,
1633
1606
ENTRY ;
1634
1607
1635
1608
bson_mutex_lock (& topology -> mutex );
1636
-
1637
1609
timeout = topology -> description .session_timeout_minutes ;
1638
1610
loadbalanced = topology -> description .type == MONGOC_TOPOLOGY_LOAD_BALANCED ;
1611
+ bson_mutex_unlock (& topology -> mutex );
1639
1612
1640
- /* start at back of queue and reap timed-out sessions */
1641
- while (topology -> session_pool && topology -> session_pool -> prev ) {
1642
- ss = topology -> session_pool -> prev ;
1643
- /* Sessions do not expire when the topology type is load balanced. */
1644
- if (!loadbalanced && _mongoc_server_session_timed_out (ss , timeout )) {
1645
- BSON_ASSERT (ss -> next ); /* silences clang scan-build */
1646
- CDL_DELETE (topology -> session_pool , ss );
1647
- _mongoc_server_session_destroy (ss );
1648
- } else {
1649
- /* if ss is not timed out, sessions in front of it are ok too */
1650
- break ;
1651
- }
1652
- }
1653
-
1654
- /* If session is expiring or "dirty" (a network error occurred on it), do not
1655
- * return it to the pool. Sessions do not expire when the topology type is
1656
- * load balanced. */
1657
1613
if ((!loadbalanced &&
1658
1614
_mongoc_server_session_timed_out (server_session , timeout )) ||
1659
1615
server_session -> dirty ) {
1660
- _mongoc_server_session_destroy (server_session );
1661
- } else {
1662
- /* silences clang scan-build */
1663
- BSON_ASSERT (!topology -> session_pool || (topology -> session_pool -> next &&
1664
- topology -> session_pool -> prev ));
1665
-
1616
+ /* If session is expiring or "dirty" (a network error occurred on it), do
1617
+ * not return it to the pool. Sessions do not expire when the topology
1618
+ * type is load balanced. */
1619
+ mongoc_ts_pool_free_item (topology -> session_pool , server_session );
1620
+ } else if (server_session -> last_used_usec == SESSION_NEVER_USED ) {
1666
1621
/* add server session (lsid) to session pool to be reused only if the
1667
1622
* server session has been used (the server is aware of the session) */
1668
- if (server_session -> last_used_usec == SESSION_NEVER_USED ) {
1669
- _mongoc_server_session_destroy (server_session );
1623
+ mongoc_ts_pool_free_item (topology -> session_pool , server_session );
1670
1624
} else {
1671
- CDL_PREPEND (topology -> session_pool , server_session );
1672
- }
1625
+ mongoc_ts_pool_push (topology -> session_pool , server_session );
1673
1626
}
1674
1627
1675
- bson_mutex_unlock (& topology -> mutex );
1676
1628
1677
1629
EXIT ;
1678
1630
}
@@ -1701,26 +1653,24 @@ _mongoc_topology_push_server_session (mongoc_topology_t *topology,
1701
1653
bool
1702
1654
_mongoc_topology_end_sessions_cmd (mongoc_topology_t * topology , bson_t * cmd )
1703
1655
{
1704
- mongoc_server_session_t * ss , * tmp1 , * tmp2 ;
1705
- char buf [16 ];
1706
- const char * key ;
1707
- uint32_t i ;
1708
1656
bson_t ar ;
1657
+ int i = 0 ;
1709
1658
1710
1659
bson_init (cmd );
1711
1660
BSON_APPEND_ARRAY_BEGIN (cmd , "endSessions" , & ar );
1712
1661
1713
- i = 0 ;
1714
- CDL_FOREACH_SAFE (topology -> session_pool , ss , tmp1 , tmp2 )
1715
- {
1716
- bson_uint32_to_string (i , & key , buf , sizeof buf );
1717
- BSON_APPEND_DOCUMENT (& ar , key , & ss -> lsid );
1718
- CDL_DELETE (topology -> session_pool , ss );
1719
- _mongoc_server_session_destroy (ss );
1720
-
1721
- if (++ i == 10000 ) {
1662
+ for (; i < 10000 ; ++ i ) {
1663
+ char buf [16 ];
1664
+ const char * key ;
1665
+ bool did_pop ;
1666
+ mongoc_server_session_t * ss =
1667
+ mongoc_ts_pool_try_pop (topology -> session_pool , & did_pop );
1668
+ if (!did_pop ) {
1722
1669
break ;
1723
1670
}
1671
+ bson_uint32_to_string (i , & key , buf , sizeof buf );
1672
+ BSON_APPEND_DOCUMENT (& ar , key , & ss -> lsid );
1673
+ mongoc_ts_pool_free_item (topology -> session_pool , ss );
1724
1674
}
1725
1675
1726
1676
bson_append_array_end (cmd , & ar );
0 commit comments