diff options
Diffstat (limited to 'server/src/connectionpool.h')
-rw-r--r-- | server/src/connectionpool.h | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/server/src/connectionpool.h b/server/src/connectionpool.h new file mode 100644 index 0000000..33473e5 --- /dev/null +++ b/server/src/connectionpool.h @@ -0,0 +1,226 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * connectionpool.h + * + * Wed Dec 16 12:20:44 CET 2009 + * Copyright 2009 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pracro. + * + * Pracro is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pracro is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pracro; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __PRACRO_CONNECTIONPOOL_H__ +#define __PRACRO_CONNECTIONPOOL_H__ + +#include <list> + +#include "mutex.h" +#include "semaphore.h" + +template <class T> +class ConnectionPool { +public: + void add(T t); + void remove(T t); + + bool testFree(T t); + int numFree(); + + T borrow(); + void giveBack(T t); + + std::list<T> clear(bool force = true); + +private: + bool contains(std::list<T> &list, T t); + + Semaphore semaphore; + Mutex mutex; + std::list<T> active; + std::list<T> passive; +}; + +template <class T> +class AutoBorrower { +public: + AutoBorrower(ConnectionPool<T> &pool); + ~AutoBorrower(); + + T get(); + +private: + ConnectionPool<T> &pool; + T t; +}; + + +// +// Implementation is below +// + +template <class T> +void ConnectionPool<T>::add(T t) +{ + MutexAutolock lock(mutex); + + passive.push_back(t); + semaphore.post(); + +} + +template <class T> +bool ConnectionPool<T>::contains(std::list<T> &list, T t) +{ + typename std::list<T>::iterator i = list.begin(); + while(i != list.end()) { + if(*i == t) return true; + i++; + } + + return false; +} + +template <class T> +void ConnectionPool<T>::remove(T t) +{ + MutexAutolock lock(mutex); + + if(contains(passive, t)) { + semaphore.post(); + passive.remove(t); + } + +} + +template <class T> +bool ConnectionPool<T>::testFree(T t) +{ + bool testfree = false; + + MutexAutolock lock(mutex); + testfree = contains(passive, t); + + return testfree; +} + +template <class T> +int ConnectionPool<T>::numFree() +{ + int num; + + MutexAutolock lock(mutex); + num = passive.size(); + + return num; +} + +template <class T> +T ConnectionPool<T>::borrow() +{ + T t = NULL; + + semaphore.wait(); + + { + MutexAutolock lock(mutex); + + t = passive.front(); + passive.remove(t); + active.push_back(t); + } + + return t; +} + +template <class T> +void ConnectionPool<T>::giveBack(T t) +{ + MutexAutolock lock(mutex); + + if(contains(active, t)) { + active.remove(t); + passive.push_back(t); + semaphore.post(); + } +} + +template <class T> +std::list<T> ConnectionPool<T>::clear(bool force) +{ + typename std::list<T> lst; + + if(force == false) { + size_t num = 0; + { + MutexAutolock lock(mutex); + num = active.size() + passive.size(); + } + + while(num) { + borrow(); + num--; + } + } + + { + MutexAutolock lock(mutex); + + typename std::list<T>::iterator i; + + i = active.begin(); + while(i != active.end()) { + lst.push_back(*i); + // i = active.erase(i); + semaphore.post(); + i++; + } + active.clear(); + + i = passive.begin(); + while(i != passive.end()) { + lst.push_back(*i); + // i = passive.erase(i); + i++; + } + passive.clear(); + } + + return lst; +} + +template <class T> +AutoBorrower<T>::AutoBorrower(ConnectionPool<T> &p) + : pool(p) +{ + t = pool.borrow(); +} + +template <class T> +AutoBorrower<T>::~AutoBorrower() +{ + pool.giveBack(t); +} + +template <class T> +T AutoBorrower<T>::get() +{ + return t; +} + +#endif/*__PRACRO_CONNECTIONPOOL_H__*/ |