Skip to content

Commit d67fb0c

Browse files
committed
Adding the connection pooling implementation and some header file cleanup
1 parent 34ea834 commit d67fb0c

File tree

6 files changed

+49
-57
lines changed

6 files changed

+49
-57
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,7 @@ Debug/
4343
*.ilk
4444
*.pdb
4545
ds3.dll
46-
/win32/output/bin
46+
/win32/output/bin
47+
.idea/
48+
cmake-build-debug/
49+
*.dylib

src/ds3.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include "ds3.h"
2727
#include "ds3_net.h"
28+
#include "ds3_connection.h"
2829
#include "ds3_request.h"
2930
#include "ds3_string_multimap_impl.h"
3031
#include "ds3_utils.h"

src/ds3_connection.c

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -20,35 +20,36 @@
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

2638
ds3_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

4242
ds3_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

8282
static 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

9192
ds3_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

120118
void 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

133133
void ds3_connection_pool_inc_ref(ds3_connection_pool* pool) {

src/ds3_connection.h

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,16 @@ extern "C" {
2626

2727
#include <curl/curl.h>
2828
#include <glib.h>
29+
#include "ds3.h"
2930

30-
#define CONNECTION_POOL_SIZE 10
31+
#define DEFAULT_CONNECTION_POOL_SIZE 10
3132

3233
typedef GMutex ds3_mutex;
3334
typedef GCond ds3_condition;
3435

3536
typedef CURL ds3_connection;
3637

37-
//-- Opaque struct
38-
struct _ds3_connection_pool{
39-
ds3_connection** connections;
40-
int* queue;
41-
uint16_t size;
42-
int head;
43-
int tail;
44-
ds3_mutex mutex;
45-
ds3_condition available_connections;
46-
uint16_t ref_count;
47-
};
38+
typedef struct _ds3_connection_pool ds3_connection_pool;
4839

4940
ds3_connection_pool* ds3_connection_pool_init(void);
5041
ds3_connection_pool* ds3_connection_pool_init_with_size(uint16_t pool_size);

src/ds3_net.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@
2020
#include <curl/curl.h>
2121

2222
#include "ds3_request.h"
23-
#include "ds3.h"
2423
#include "ds3_net.h"
2524
#include "ds3_utils.h"
26-
#include "ds3_string_multimap.h"
2725
#include "ds3_string_multimap_impl.h"
2826
#include "ds3_connection.h"
2927

src/ds3_net.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ extern "C" {
2626

2727
#include "ds3.h"
2828
#include "ds3_string_multimap.h"
29-
#include "ds3_connection.h"
3029

3130
char* escape_url(const char* url);
3231
char* escape_url_extended(const char* url, const char** delimiters, uint32_t num_delimiters);

0 commit comments

Comments
 (0)