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