Skip to content

Commit 64a395c

Browse files
Andrew WittenkevinAlbs
authored andcommitted
CDRIVER-3757 inits pool cond, adds test (#666)
Initializes pool condition variable. Adds (non-deterministic) test for the case where a thread is waiting in call to `mongoc_client_pool_pop` for a client to become available.
1 parent f4076b8 commit 64a395c

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

src/libmongoc/src/mongoc/mongoc-client-pool.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ mongoc_client_pool_new (const mongoc_uri_t *uri)
117117

118118
pool = (mongoc_client_pool_t *) bson_malloc0 (sizeof *pool);
119119
bson_mutex_init (&pool->mutex);
120+
mongoc_cond_init (&pool->cond);
120121
_mongoc_queue_init (&pool->queue);
121122
pool->uri = mongoc_uri_copy (uri);
122123
pool->min_pool_size = 0;

src/libmongoc/tests/test-mongoc-client-pool.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,68 @@ test_client_pool_create_unused_session (void *context)
405405
ASSERT_NO_CAPTURED_LOGS ("mongoc_client_pool_destroy");
406406
}
407407

408+
409+
/* Tests case where thread is blocked waiting for a client to be pushed back
410+
* into the client pool. Specifically this tests that the program terminates.
411+
* Addresses CDRIVER-3757 */
412+
typedef struct pool_timeout {
413+
mongoc_client_pool_t *pool;
414+
bson_mutex_t mutex;
415+
mongoc_cond_t cond;
416+
int nleft;
417+
} pool_timeout_args_t;
418+
419+
static BSON_THREAD_FUN (worker, arg)
420+
{
421+
pool_timeout_args_t *args = arg;
422+
mongoc_client_t *client = mongoc_client_pool_pop (args->pool);
423+
BSON_ASSERT (client);
424+
_mongoc_usleep (10);
425+
mongoc_client_pool_push (args->pool, client);
426+
bson_mutex_lock (&args->mutex);
427+
/* notify main thread that current thread has terminated */
428+
args->nleft--;
429+
mongoc_cond_signal (&args->cond);
430+
bson_mutex_unlock (&args->mutex);
431+
BSON_THREAD_RETURN;
432+
}
433+
434+
static void
435+
test_client_pool_max_pool_size_exceeded (void)
436+
{
437+
mongoc_client_pool_t *pool;
438+
mongoc_uri_t *uri;
439+
bson_thread_t thread1, thread2;
440+
pool_timeout_args_t *args = bson_malloc0 (sizeof (pool_timeout_args_t));
441+
int wait_time = 4000; /* 4000 msec = 4 sec */
442+
int ret;
443+
444+
uri = mongoc_uri_new ("mongodb://127.0.0.1/?maxpoolsize=1");
445+
pool = mongoc_client_pool_new (uri);
446+
args->pool = pool;
447+
args->nleft = 2;
448+
bson_mutex_init (&args->mutex);
449+
mongoc_cond_init (&args->cond);
450+
451+
COMMON_PREFIX (thread_create) (&thread1, worker, args);
452+
COMMON_PREFIX (thread_create) (&thread2, worker, args);
453+
454+
bson_mutex_lock (&args->mutex);
455+
while (args->nleft > 0) {
456+
ret = mongoc_cond_timedwait (&args->cond, &args->mutex, wait_time);
457+
/* ret non-zero indicates an error (a timeout) */
458+
BSON_ASSERT (!ret);
459+
}
460+
bson_mutex_unlock (&args->mutex);
461+
462+
COMMON_PREFIX (thread_join) (thread1);
463+
COMMON_PREFIX (thread_join) (thread2);
464+
465+
mongoc_uri_destroy (uri);
466+
mongoc_client_pool_destroy (pool);
467+
bson_free (args);
468+
}
469+
408470
void
409471
test_client_pool_install (TestSuite *suite)
410472
{
@@ -440,4 +502,7 @@ test_client_pool_install (TestSuite *suite)
440502
TestSuite_AddLive (suite,
441503
"/ClientPool/destroy_without_push",
442504
test_client_pool_destroy_without_pushing);
505+
TestSuite_AddLive (suite,
506+
"/ClientPool/max_pool_size_exceeded",
507+
test_client_pool_max_pool_size_exceeded);
443508
}

0 commit comments

Comments
 (0)