1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* 3 * Copyright 2013 Couchbase, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #include "pool.h" 19 20 using namespace lcb; 21 using std::queue; 22 using std::vector; 23 24 Pool::Pool(const lcb_create_st& options, size_t nitems) : initial_size(0) 25 { 26 pthread_mutex_init(&mutex, NULL); 27 pthread_cond_init(&cond, NULL); 28 for (size_t ii = 0; ii < nitems; ii++) { 29 lcb_t cur; 30 lcb_error_t err = lcb_create(&cur, &options); 31 if (err != LCB_SUCCESS) { 32 throw err; 33 } 34 35 instances.push(cur); fsm_page_contents(PG_FUNCTION_ARGS)36 all_instances.push_back(cur); 37 initial_size++; 38 } 39 } 40 41 lcb_error_t 42 Pool::connect() 43 { 44 vector<lcb_t>::const_iterator ii = all_instances.begin(); 45 for (; ii != all_instances.end(); ii++) { 46 lcb_error_t err; 47 initialize(*ii); 48 if ((err = lcb_connect(*ii)) != LCB_SUCCESS) { 49 return err; 50 } 51 lcb_wait(*ii); 52 if ((err = lcb_get_bootstrap_status(*ii)) != LCB_SUCCESS) { 53 return err; 54 } 55 } 56 return LCB_SUCCESS; 57 } 58 59 Pool::~Pool() 60 { 61 pthread_mutex_lock(&mutex); 62 while (instances.size() < initial_size) { 63 pthread_cond_wait(&cond, &mutex); 64 } 65 vector<lcb_t>::const_iterator ii = all_instances.begin(); 66 for (; ii != all_instances.end(); ii++) { 67 lcb_destroy(*ii); 68 } 69 pthread_mutex_unlock(&mutex); 70 pthread_mutex_destroy(&mutex); 71 pthread_cond_destroy(&cond); 72 } 73 74 lcb_t 75 Pool::pop() 76 { 77 lcb_t ret = NULL; 78 79 // Need to lock the mutex to the pool structure itself 80 pthread_mutex_lock(&mutex); 81 82 while (instances.empty()) { 83 pthread_cond_wait(&cond, &mutex); 84 } 85 86 ret = instances.front(); 87 instances.pop(); 88 pthread_mutex_unlock(&mutex); 89 90 // Note that the instance itself does not need a mutex as long as it is not 91 // used between multiple threads concurrently. 92 return ret; 93 } 94 95 void 96 Pool::push(lcb_t instance) 97 { 98 pthread_mutex_lock(&mutex); 99 instances.push(instance); 100 pthread_cond_signal(&cond); 101 pthread_mutex_unlock(&mutex); 102 } 103