1 #include "libmemcached/common.h"
2 #include "libmemcached/memcached_pool.h"
7 struct memcached_pool_st
15 uint32_t current_size
;
18 static memcached_return
mutex_enter(pthread_mutex_t
*mutex
)
22 ret
= pthread_mutex_lock(mutex
);
23 while (ret
== -1 && errno
== EINTR
);
25 return (ret
== -1) ? MEMCACHED_ERRNO
: MEMCACHED_SUCCESS
;
28 static memcached_return
mutex_exit(pthread_mutex_t
*mutex
) {
31 ret
= pthread_mutex_unlock(mutex
);
32 while (ret
== -1 && errno
== EINTR
);
34 return (ret
== -1) ? MEMCACHED_ERRNO
: MEMCACHED_SUCCESS
;
38 * Grow the connection pool by creating a connection structure and clone the
39 * original memcached handle.
41 static int grow_pool(memcached_pool_st
* pool
) {
42 memcached_st
*obj
= calloc(1, sizeof(*obj
));
46 if (memcached_clone(obj
, pool
->master
) == NULL
)
52 pool
->mmc
[++pool
->firstfree
] = obj
;
58 memcached_pool_st
*memcached_pool_create(memcached_st
* mmc
,
59 uint32_t initial
, uint32_t max
)
61 memcached_pool_st
* ret
= NULL
;
62 memcached_pool_st object
= { .mutex
= PTHREAD_MUTEX_INITIALIZER
,
63 .cond
= PTHREAD_COND_INITIALIZER
,
65 .mmc
= calloc(max
, sizeof(memcached_st
*)),
70 if (object
.mmc
!= NULL
)
72 ret
= calloc(1, sizeof(*ret
));
81 /* Try to create the initial size of the pool. An allocation failure at
82 * this time is not fatal..
84 for (unsigned int ii
=0; ii
< initial
; ++ii
)
85 if (grow_pool(ret
) == -1)
92 memcached_st
* memcached_pool_destroy(memcached_pool_st
* pool
)
94 memcached_st
*ret
= pool
->master
;
96 for (int xx
= 0; xx
<= pool
->firstfree
; ++xx
)
98 memcached_free(pool
->mmc
[xx
]);
100 pool
->mmc
[xx
] = NULL
;
103 pthread_mutex_destroy(&pool
->mutex
);
104 pthread_cond_destroy(&pool
->cond
);
111 memcached_st
* memcached_pool_pop(memcached_pool_st
* pool
,
113 memcached_return
*rc
)
115 memcached_st
*ret
= NULL
;
116 if ((*rc
= mutex_enter(&pool
->mutex
)) != MEMCACHED_SUCCESS
)
121 if (pool
->firstfree
> -1)
122 ret
= pool
->mmc
[pool
->firstfree
--];
123 else if (pool
->current_size
== pool
->size
)
127 *rc
= mutex_exit(&pool
->mutex
);
131 if (pthread_cond_wait(&pool
->cond
, &pool
->mutex
) == -1)
134 mutex_exit(&pool
->mutex
);
136 *rc
= MEMCACHED_ERRNO
;
140 else if (grow_pool(pool
) == -1)
142 *rc
= mutex_exit(&pool
->mutex
);
148 *rc
= mutex_exit(&pool
->mutex
);
153 memcached_return
memcached_pool_push(memcached_pool_st
* pool
,
156 memcached_return rc
= mutex_enter(&pool
->mutex
);
158 if (rc
!= MEMCACHED_SUCCESS
)
161 pool
->mmc
[++pool
->firstfree
]= mmc
;
163 if (pool
->firstfree
== 0 && pool
->current_size
== pool
->size
)
165 /* we might have people waiting for a connection.. wake them up :-) */
166 pthread_cond_broadcast(&pool
->cond
);
169 return mutex_exit(&pool
->mutex
);