2020#include <string.h>
2121#include <curl/curl.h>
2222#include <glib.h>
23+ #include <inttypes.h>
2324#include "ds3_net.h"
2425
2526ds3_connection_pool * ds3_connection_pool_init (void ) {
27+ return ds3_connection_pool_init_with_size (CONNECTION_POOL_SIZE );
28+ }
29+
30+ ds3_connection_pool * ds3_connection_pool_init_with_size (uint16_t pool_size ) {
2631 ds3_connection_pool * pool = g_new0 (ds3_connection_pool , 1 );
32+ pool -> connections = g_new0 (ds3_connection * , pool_size );
33+ pool -> num_connections = pool_size ;
2734 g_mutex_init (& pool -> mutex );
2835 g_cond_init (& pool -> available_connections );
36+ pool -> ref_count = 1 ;
2937 return pool ;
3038}
3139
32- void ds3_connection_pool_clear (ds3_connection_pool * pool ) {
40+ void ds3_connection_pool_clear (ds3_connection_pool * pool , ds3_bool already_locked ) {
3341 int index ;
3442
3543 if (pool == NULL ) {
3644 return ;
3745 }
3846
39- g_mutex_lock (& pool -> mutex );
47+ if (already_locked == False ) {
48+ g_mutex_lock (& pool -> mutex );
49+ }
4050
41- for (index = 0 ; index < CONNECTION_POOL_SIZE ; index ++ ) {
51+ for (index = 0 ; index < pool -> num_connections ; index ++ ) {
4252 if (pool -> connections [index ] != NULL ) {
4353 curl_easy_cleanup (pool -> connections [index ]);
4454 }
4555 }
4656
57+ g_free (pool -> connections );
4758 g_mutex_unlock (& pool -> mutex );
48- g_mutex_clear (& pool -> mutex );
59+ g_mutex_clear (& pool -> mutex ); // an attempt to clear a locked mutex is undefined
4960 g_cond_clear (& pool -> available_connections );
5061}
5162
52- static int _pool_inc (ds3_connection_pool * pool , int index ) {
53- return (index + 1 ) % CONNECTION_POOL_SIZE ;
63+ static int _pool_inc (int index , uint16_t num_connections ) {
64+ return (index + 1 ) % num_connections ;
5465}
5566
5667static int _pool_full (ds3_connection_pool * pool ) {
57- return (_pool_inc (pool , pool -> tail ) == pool -> head );
68+ return (_pool_inc (pool -> head , pool -> num_connections ) == pool -> tail );
5869}
5970
6071
@@ -73,7 +84,7 @@ ds3_connection* ds3_connection_acquire(ds3_connection_pool* pool) {
7384 } else {
7485 connection = pool -> connections [pool -> head ];
7586 }
76- pool -> head = _pool_inc (pool , pool -> head );
87+ pool -> head = _pool_inc (pool -> head , pool -> num_connections );
7788
7889 g_mutex_unlock (& pool -> mutex );
7990
@@ -82,11 +93,27 @@ ds3_connection* ds3_connection_acquire(ds3_connection_pool* pool) {
8293
8394void ds3_connection_release (ds3_connection_pool * pool , ds3_connection * connection ) {
8495 g_mutex_lock (& pool -> mutex );
85-
8696 curl_easy_reset (connection );
87- pool -> tail = _pool_inc (pool , pool -> tail );
97+ pool -> tail = _pool_inc (pool -> tail , pool -> num_connections );
8898
8999 g_mutex_unlock (& pool -> mutex );
90100 g_cond_signal (& pool -> available_connections );
91101}
92102
103+ void ds3_connection_pool_inc_ref (ds3_connection_pool * pool ) {
104+ g_mutex_lock (& pool -> mutex );
105+ pool -> ref_count ++ ;
106+ g_mutex_unlock (& pool -> mutex );
107+ }
108+
109+ void ds3_connection_pool_dec_ref (ds3_connection_pool * pool ) {
110+ g_mutex_lock (& pool -> mutex );
111+ pool -> ref_count -- ;
112+
113+ if (pool -> ref_count == 0 ) {
114+ ds3_connection_pool_clear (pool , True );
115+ g_free (pool );
116+ } else {
117+ g_mutex_unlock (& pool -> mutex );
118+ }
119+ }
0 commit comments