2020#include <curl/curl.h>
2121#include <glib.h>
2222#include <inttypes.h>
23- #include "ds3_net.h"
24-
23+ #include "ds3_connection.h"
24+
25+ //-- Opaque struct
26+ struct _ds3_connection_pool {
27+ ds3_connection * * connections ;
28+ uint16_t num_connections ; // the number of connections created
29+ ds3_connection * * connection_queue ;
30+ uint16_t max_connections ; // max number of possible connections, which the connections and queue arrays will be initialized to
31+ int queue_head ;
32+ int queue_tail ;
33+ ds3_mutex mutex ;
34+ ds3_condition available_connection_notifier ;
35+ uint16_t ref_count ;
36+ };
2537
2638ds3_connection_pool * ds3_connection_pool_init (void ) {
27- return ds3_connection_pool_init_with_size (CONNECTION_POOL_SIZE );
28- }
29-
30- void _ds3_queue_init (ds3_connection_pool * pool ) {
31- int index ;
32- pool -> queue = g_new0 (int , pool -> size );
33- for (index = 0 ; index < pool -> size ; index ++ ) {
34- pool -> queue [index ] = index ; // init to default
35- }
36- }
37-
38- void _ds3_queue_free (ds3_connection_pool * pool ) {
39- g_free (pool -> queue );
39+ return ds3_connection_pool_init_with_size (DEFAULT_CONNECTION_POOL_SIZE );
4040}
4141
4242ds3_connection_pool * ds3_connection_pool_init_with_size (uint16_t pool_size ) {
4343 printf ("ds3_connection_pool_init_with_size(%u)\n" , pool_size );
4444 ds3_connection_pool * pool = g_new0 (ds3_connection_pool , 1 );
45+
4546 pool -> connections = g_new0 (ds3_connection * , pool_size );
46- pool -> size = pool_size ;
47+ pool -> connection_queue = g_new0 ( ds3_connection * , pool_size ) ;
4748
48- _ds3_queue_init ( pool ) ;
49+ pool -> max_connections = pool_size ;
4950
5051 g_mutex_init (& pool -> mutex );
51- g_cond_init (& pool -> available_connections );
52+ g_cond_init (& pool -> available_connection_notifier );
5253 pool -> ref_count = 1 ;
5354 return pool ;
5455}
@@ -65,69 +66,68 @@ void ds3_connection_pool_clear(ds3_connection_pool* pool, ds3_bool already_locke
6566 }
6667 printf ("ds3_connection_pool_clear(%s)\n" , (already_locked ? "locked" : "not locked" ));
6768
68- for (index = 0 ; index < pool -> size ; index ++ ) {
69+ for (index = 0 ; index < pool -> num_connections ; index ++ ) {
6970 if (pool -> connections [index ] != NULL ) {
7071 curl_easy_cleanup (pool -> connections [index ]);
7172 }
7273 }
7374
74- _ds3_queue_free (pool );
75-
7675 g_free (pool -> connections );
76+ g_free (pool -> connection_queue );
7777 g_mutex_unlock (& pool -> mutex );
7878 g_mutex_clear (& pool -> mutex ); // an attempt to clear a locked mutex is undefined
79- g_cond_clear (& pool -> available_connections );
79+ g_cond_clear (& pool -> available_connection_notifier );
8080}
8181
8282static int _queue_inc (int index , uint16_t size ) {
8383 printf ("_pool_inc(%d, %u) :[%d]\n" , index , size , (index + 1 ) % size );
8484 return (index + 1 ) % size ;
8585}
8686
87- static int _queue_full (ds3_connection_pool * pool ) {
88- return (_pool_inc (pool -> head , pool -> size ) == pool -> tail );
87+ static int _queue_is_empty (ds3_connection_pool * pool ) {
88+ int queue_head = pool -> queue_head ;
89+ return pool -> queue_tail == queue_head && pool -> connection_queue [queue_head ] == NULL ;
8990}
9091
9192ds3_connection * ds3_connection_acquire (ds3_connection_pool * pool ) {
9293 ds3_connection * connection = NULL ;
93- int next_connection_index ;
9494
9595 g_mutex_lock (& pool -> mutex );
96- printf ("ds3_connection_acquire() BEGIN: head[%d] tail[%d]\n" , pool -> head , pool -> tail );
97- while (_pool_full (pool )) {
98- g_cond_wait (& pool -> available_connections , & pool -> mutex );
96+ printf ("ds3_connection_acquire() BEGIN: head[%d] tail[%d]\n" , pool -> queue_head , pool -> queue_tail );
97+ while (_queue_is_empty (pool ) && pool -> num_connections >= pool -> max_connections ) {
98+ g_cond_wait (& pool -> available_connection_notifier , & pool -> mutex );
9999 }
100100
101- next_connection_index = pool -> queue [pool -> head ];
102- pool -> queue [pool -> head ] = -1 ; // invalid while in use
103- if (pool -> connections [next_connection_index ] == NULL ) {
104- connection = g_new0 (ds3_connection , 1 );
101+ if (_queue_is_empty (pool )) {
105102 connection = curl_easy_init ();
106103
107- pool -> connections [next_connection_index ] = connection ;
104+ pool -> connections [pool -> num_connections ] = connection ;
105+ pool -> num_connections ++ ;
108106 } else {
109- connection = pool -> connections [next_connection_index ];
107+ connection = pool -> connection_queue [pool -> queue_tail ];
108+ pool -> connection_queue [pool -> queue_tail ] = NULL ;
109+ pool -> queue_tail = _queue_inc (pool -> queue_tail , pool -> max_connections );
110110 }
111- pool -> queue [pool -> tail ] = pool -> head ;
112- pool -> head = _pool_inc (pool -> head , pool -> size );
113111
114- printf ("ds3_connection_acquire() END: head[%d] tail[%d]\n" , pool -> head , pool -> tail );
112+ printf ("ds3_connection_acquire() END: head[%d] tail[%d]\n" , pool -> queue_head , pool -> queue_tail );
115113 g_mutex_unlock (& pool -> mutex );
116114
117115 return connection ;
118116}
119117
120118void ds3_connection_release (ds3_connection_pool * pool , ds3_connection * connection ) {
121119 g_mutex_lock (& pool -> mutex );
122- printf ("ds3_connection_release() BEGIN: head[%d] tail[%d]\n" , pool -> head , pool -> tail );
120+ printf ("ds3_connection_release() BEGIN: head[%d] tail[%d]\n" , pool -> queue_head , pool -> queue_tail );
123121
124122 curl_easy_reset (connection );
125123
126- pool -> tail = _pool_inc (pool -> tail , pool -> size );
124+ pool -> connection_queue [pool -> queue_head ] = connection ;
125+
126+ pool -> queue_head = _queue_inc (pool -> queue_head , pool -> max_connections );
127127
128- printf ("ds3_connection_release() END: head[%d] tail[%d]\n" , pool -> head , pool -> tail );
128+ printf ("ds3_connection_release() END: head[%d] tail[%d]\n" , pool -> queue_head , pool -> queue_tail );
129+ g_cond_signal (& pool -> available_connection_notifier );
129130 g_mutex_unlock (& pool -> mutex );
130- g_cond_signal (& pool -> available_connections );
131131}
132132
133133void ds3_connection_pool_inc_ref (ds3_connection_pool * pool ) {
0 commit comments