testing: pools + mac
[awesomized/libmemcached] / test / tests / memcached / util_pool_thread.cpp
1 #include "test/lib/common.hpp"
2
3 #if HAVE_SEMAPHORE_H
4
5 #include "libmemcachedutil-1.0/pool.h"
6 #include <cassert>
7 #include "semaphore.h"
8
9 struct test_pool_context_st {
10 volatile memcached_return_t rc;
11 memcached_pool_st *pool;
12 memcached_st *memc;
13 sem_t _lock;
14
15 test_pool_context_st(memcached_pool_st *pool_arg, memcached_st *memc_arg) :
16 rc(MEMCACHED_FAILURE),
17 pool(pool_arg),
18 memc(memc_arg) {
19 if (sem_init(&_lock, 0, 0)) {
20 perror("sem_init()");
21 }
22 }
23
24 void wait() {
25 sem_wait(&_lock);
26 }
27
28 void release() {
29 sem_post(&_lock);
30 }
31
32 ~test_pool_context_st() {
33 sem_destroy(&_lock);
34 }
35 };
36
37 static void *connection_release(void *arg) {
38 assert(arg != nullptr);
39
40 this_thread::sleep_for(200ms);
41 auto res = static_cast<test_pool_context_st *>(arg);
42 res->rc = memcached_pool_release(res->pool, res->memc);
43 res->release();
44
45 pthread_exit(arg);
46 }
47
48 TEST_CASE("memcached_util_pool_thread") {
49 MemcachedPtr memc;
50 auto pool = memcached_pool_create(*memc, 1, 1);
51 REQUIRE(pool);
52
53 memcached_return_t rc;
54 auto pool_memc = memcached_pool_fetch(pool, nullptr, &rc);
55 REQUIRE(MEMCACHED_SUCCESS == rc);
56 REQUIRE(pool_memc);
57
58 /*
59 @note This comment was written to describe what was believed to be the original authors intent.
60
61 This portion of the test creates a thread that will wait until told to free a memcached_st
62 that will be grabbed by the main thread.
63
64 It is believed that this tests whether or not we are handling ownership correctly.
65 */
66 pthread_t tid;
67 test_pool_context_st item(pool, pool_memc);
68
69 REQUIRE(0 == pthread_create(&tid, nullptr, connection_release, &item));
70 item.wait();
71
72 memcached_st *pop_memc;
73 do {
74 struct timespec relative_time = {0, 0};
75 pop_memc = memcached_pool_fetch(pool, &relative_time, &rc);
76
77 if (memcached_success(rc)) {
78 break;
79 }
80
81 if (memcached_failed(rc)) {
82 REQUIRE_FALSE(pop_memc);
83 REQUIRE(rc != MEMCACHED_TIMEOUT); // As long as relative_time is zero, MEMCACHED_TIMEOUT is invalid
84 }
85 } while (rc == MEMCACHED_NOTFOUND);
86
87 // Cleanup thread since we will exit once we test.
88 REQUIRE(0 == pthread_join(tid, nullptr));
89 REQUIRE(MEMCACHED_SUCCESS == rc);
90 REQUIRE(pool_memc == pop_memc);
91 REQUIRE(MEMCACHED_SUCCESS == memcached_pool_release(pool, pop_memc));
92 REQUIRE(memcached_pool_destroy(pool) == *memc);
93
94 }
95
96 #endif // HAVE_SEMAPHORE_H