@@ -105,14 +105,20 @@ struct conn_pool {
105105};
106106
107107static struct lock conn_pools_mtx ;
108+ static struct lock dead_pools_mtx ;
108109
109- static VRBT_HEAD (vrb , conn_pool ) conn_pools = VRBT_INITIALIZER ( & conn_pools );
110+ VRBT_HEAD (vrb , conn_pool );
110111VRBT_GENERATE_REMOVE_COLOR (vrb , conn_pool , entry , static )
111112VRBT_GENERATE_REMOVE (vrb , conn_pool , entry , static )
112113VRBT_GENERATE_FIND (vrb , conn_pool , entry , vcp_cmp , static )
113114VRBT_GENERATE_INSERT_COLOR (vrb , conn_pool , entry , static )
114115VRBT_GENERATE_INSERT_FINISH (vrb , conn_pool , entry , static )
115116VRBT_GENERATE_INSERT (vrb , conn_pool , entry , vcp_cmp , static )
117+ VRBT_GENERATE_NEXT (vrb , conn_pool , entry , static );
118+ VRBT_GENERATE_MINMAX (vrb , conn_pool , entry , static );
119+
120+ static struct vrb conn_pools = VRBT_INITIALIZER (& conn_pools );
121+ static struct vrb dead_pools = VRBT_INITIALIZER (& dying_cps );
116122
117123/*--------------------------------------------------------------------
118124 */
@@ -217,6 +223,22 @@ VCP_AddRef(struct conn_pool *cp)
217223 Lck_Unlock (& conn_pools_mtx );
218224}
219225
226+ /*--------------------------------------------------------------------
227+ */
228+
229+ static void
230+ vcp_destroy (struct conn_pool * * cpp )
231+ {
232+ struct conn_pool * cp ;
233+
234+ TAKE_OBJ_NOTNULL (cp , cpp , CONN_POOL_MAGIC );
235+ AZ (cp -> n_conn );
236+ AZ (cp -> n_kill );
237+ Lck_Delete (& cp -> mtx );
238+ free (cp -> endpoint );
239+ FREE_OBJ (cp );
240+ }
241+
220242/*--------------------------------------------------------------------
221243 * Release Conn pool, destroy if last reference.
222244 */
@@ -248,17 +270,57 @@ VCP_Rel(struct conn_pool **cpp)
248270 (void )shutdown (pfd -> fd , SHUT_RDWR );
249271 cp -> n_kill ++ ;
250272 }
251- while (cp -> n_kill ) {
252- Lck_Unlock (& cp -> mtx );
253- (void )usleep (20000 );
254- Lck_Lock (& cp -> mtx );
255- }
256273 Lck_Unlock (& cp -> mtx );
257- Lck_Delete (& cp -> mtx );
258- AZ (cp -> n_conn );
259- AZ (cp -> n_kill );
260- free (cp -> endpoint );
261- FREE_OBJ (cp );
274+ if (cp -> n_kill == 0 ) {
275+ vcp_destroy (& cp );
276+ return ;
277+ }
278+ Lck_Lock (& dead_pools_mtx );
279+ /*
280+ * Here we reuse cp's entry but it will probably not be correctly
281+ * indexed because of the hack in VCP_RelPoll
282+ */
283+ VRBT_INSERT (vrb , & dead_pools , cp );
284+ Lck_Unlock (& dead_pools_mtx );
285+ }
286+
287+ void
288+ VCP_RelPoll (void )
289+ {
290+ struct vrb dead ;
291+ struct conn_pool * cp , * cp2 ;
292+
293+ ASSERT_CLI ();
294+
295+ Lck_Lock (& dead_pools_mtx );
296+ if (VRBT_EMPTY (& dead_pools )) {
297+ Lck_Unlock (& dead_pools_mtx );
298+ return ;
299+ }
300+ dead = dead_pools ;
301+ VRBT_INIT (& dead_pools );
302+ Lck_Unlock (& dead_pools_mtx );
303+
304+ VRBT_FOREACH_SAFE (cp , vrb , & dead , cp2 ) {
305+ CHECK_OBJ_NOTNULL (cp , CONN_POOL_MAGIC );
306+ if (cp -> n_kill > 0 )
307+ continue ;
308+ VRBT_REMOVE (vrb , & dead , cp );
309+ vcp_destroy (& cp );
310+ }
311+
312+ if (VRBT_EMPTY (& dead ))
313+ return ;
314+
315+ Lck_Lock (& dead_pools_mtx );
316+ /*
317+ * The following insertion will most likely result in an
318+ * unordered tree, but in this case it does not matter
319+ * as we just want to iterate over all the elements
320+ * in the tree in order to delete them.
321+ */
322+ VRBT_INSERT (vrb , & dead_pools , dead .rbh_root );
323+ Lck_Unlock (& dead_pools_mtx );
262324}
263325
264326/*--------------------------------------------------------------------
582644VCP_Init (void )
583645{
584646 Lck_New (& conn_pools_mtx , lck_conn_pool );
647+ Lck_New (& dead_pools_mtx , lck_dead_pool );
585648}
586649
587650/**********************************************************************/
0 commit comments