#include "pool.h"
using namespace lcb;
using std::queue;
using std::vector;
Pool::Pool(const lcb_create_st& options, size_t nitems) : initial_size(0)
{
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
for (size_t ii = 0; ii < nitems; ii++) {
lcb_t cur;
lcb_error_t err = lcb_create(&cur, &options);
if (err != LCB_SUCCESS) {
throw err;
}
instances.push(cur);
all_instances.push_back(cur);
initial_size++;
}
}
lcb_error_t
Pool::connect()
{
vector<lcb_t>::const_iterator ii = all_instances.begin();
for (; ii != all_instances.end(); ii++) {
lcb_error_t err;
initialize(*ii);
if ((err = lcb_connect(*ii)) != LCB_SUCCESS) {
return err;
}
lcb_wait(*ii);
if ((err = lcb_get_bootstrap_status(*ii)) != LCB_SUCCESS) {
return err;
}
}
return LCB_SUCCESS;
}
Pool::~Pool()
{
pthread_mutex_lock(&mutex);
while (instances.size() < initial_size) {
pthread_cond_wait(&cond, &mutex);
}
vector<lcb_t>::const_iterator ii = all_instances.begin();
for (; ii != all_instances.end(); ii++) {
lcb_destroy(*ii);
}
pthread_mutex_unlock(&mutex);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
}
lcb_t
Pool::pop()
{
lcb_t ret = NULL;
pthread_mutex_lock(&mutex);
while (instances.empty()) {
pthread_cond_wait(&cond, &mutex);
}
ret = instances.front();
instances.pop();
pthread_mutex_unlock(&mutex);
return ret;
}
void
Pool::push(lcb_t instance)
{
pthread_mutex_lock(&mutex);
instances.push(instance);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}