From 74a28aa7125be6a603128ad600c98c4882f3b5c2 Mon Sep 17 00:00:00 2001 From: deva Date: Tue, 1 Jun 2010 12:58:32 +0000 Subject: From new_protocol branch. --- server/src/connectionpool.h | 226 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 server/src/connectionpool.h (limited to 'server/src/connectionpool.h') 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 + +#include "mutex.h" +#include "semaphore.h" + +template +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 clear(bool force = true); + +private: + bool contains(std::list &list, T t); + + Semaphore semaphore; + Mutex mutex; + std::list active; + std::list passive; +}; + +template +class AutoBorrower { +public: + AutoBorrower(ConnectionPool &pool); + ~AutoBorrower(); + + T get(); + +private: + ConnectionPool &pool; + T t; +}; + + +// +// Implementation is below +// + +template +void ConnectionPool::add(T t) +{ + MutexAutolock lock(mutex); + + passive.push_back(t); + semaphore.post(); + +} + +template +bool ConnectionPool::contains(std::list &list, T t) +{ + typename std::list::iterator i = list.begin(); + while(i != list.end()) { + if(*i == t) return true; + i++; + } + + return false; +} + +template +void ConnectionPool::remove(T t) +{ + MutexAutolock lock(mutex); + + if(contains(passive, t)) { + semaphore.post(); + passive.remove(t); + } + +} + +template +bool ConnectionPool::testFree(T t) +{ + bool testfree = false; + + MutexAutolock lock(mutex); + testfree = contains(passive, t); + + return testfree; +} + +template +int ConnectionPool::numFree() +{ + int num; + + MutexAutolock lock(mutex); + num = passive.size(); + + return num; +} + +template +T ConnectionPool::borrow() +{ + T t = NULL; + + semaphore.wait(); + + { + MutexAutolock lock(mutex); + + t = passive.front(); + passive.remove(t); + active.push_back(t); + } + + return t; +} + +template +void ConnectionPool::giveBack(T t) +{ + MutexAutolock lock(mutex); + + if(contains(active, t)) { + active.remove(t); + passive.push_back(t); + semaphore.post(); + } +} + +template +std::list ConnectionPool::clear(bool force) +{ + typename std::list 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::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 +AutoBorrower::AutoBorrower(ConnectionPool &p) + : pool(p) +{ + t = pool.borrow(); +} + +template +AutoBorrower::~AutoBorrower() +{ + pool.giveBack(t); +} + +template +T AutoBorrower::get() +{ + return t; +} + +#endif/*__PRACRO_CONNECTIONPOOL_H__*/ -- cgit v1.2.3