summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeva <deva>2009-12-17 12:45:20 +0000
committerdeva <deva>2009-12-17 12:45:20 +0000
commitf74d220ba0723b38faeef5aeca39cd627dc3340d (patch)
treef9723da4d337c1d8fa8302be2bd6e825f8eddd56
parentbe4fc7990b91e1fb053df4a1388f13aaad9772f8 (diff)
Added connection pool class. Using semaphores (also added)
-rw-r--r--server/src/connectionpool.cc215
-rw-r--r--server/src/connectionpool.h70
-rw-r--r--server/src/semaphore.cc47
-rw-r--r--server/src/semaphore.h44
4 files changed, 376 insertions, 0 deletions
diff --git a/server/src/connectionpool.cc b/server/src/connectionpool.cc
new file mode 100644
index 0000000..09dd5d1
--- /dev/null
+++ b/server/src/connectionpool.cc
@@ -0,0 +1,215 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * connectionpool.cc
+ *
+ * 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.
+ */
+#include "connectionpool.h"
+
+ConnectionPool::ConnectionPool()
+{
+}
+
+void ConnectionPool::addDatabase(Database *db)
+{
+ mutex.lock();
+ passivedbs.push_back(db);
+ semaphore.post();
+ mutex.unlock();
+}
+
+static inline bool contains(std::list<Database *> list, Database *db)
+{
+ std::list<Database*>::iterator i = list.begin();
+ while(i != list.end()) {
+ if(*i == db) return true;
+ i++;
+ }
+ return false;
+}
+
+void ConnectionPool::removeDatabase(Database *db)
+{
+ mutex.lock();
+ if(contains(passivedbs, db)) {
+ semaphore.post();
+ passivedbs.remove(db);
+ }
+ mutex.unlock();
+}
+
+bool ConnectionPool::testFree(Database *db)
+{
+ bool testfree = false;
+
+ mutex.lock();
+ testfree = contains(passivedbs, db);
+ mutex.unlock();
+
+ return testfree;
+}
+
+int ConnectionPool::numFreeDatabases()
+{
+ int num;
+ mutex.lock();
+ num = passivedbs.size();
+ mutex.unlock();
+ return num;
+}
+
+#include <stdio.h>
+Database *ConnectionPool::borrowDatabase()
+{
+ Database *db = NULL;
+
+ semaphore.wait();
+
+ mutex.lock();
+
+ db = passivedbs.front();
+ passivedbs.remove(db);
+ activedbs.push_back(db);
+
+ mutex.unlock();
+
+ return db;
+}
+
+void ConnectionPool::returnDatabase(Database *db)
+{
+ mutex.lock();
+
+ if(contains(activedbs, db)) {
+ activedbs.remove(db);
+ passivedbs.push_back(db);
+ semaphore.post();
+ }
+
+ mutex.unlock();
+}
+
+AutoBorrower::AutoBorrower(ConnectionPool &p)
+ : pool(p)
+{
+ _db = pool.borrowDatabase();
+}
+
+AutoBorrower::~AutoBorrower()
+{
+ pool.returnDatabase(_db);
+}
+
+Database *AutoBorrower::db()
+{
+ return _db;
+}
+
+
+#ifdef TEST_CONNECTIONPOOL
+//deps: mutex.cc semaphore.cc
+//cflags:
+//libs: -lpthread
+#include <test.h>
+#include <unistd.h>
+#include <pthread.h>
+
+static void* thread_run(void *data)
+{
+ ConnectionPool *pool = (ConnectionPool*)data;
+
+ Database *db1 = pool->borrowDatabase();
+ Database *db2 = pool->borrowDatabase();
+ Database *db3 = pool->borrowDatabase();
+ Database *db4 = pool->borrowDatabase();
+
+ usleep(100);
+
+ pool->returnDatabase(db1);
+ pool->returnDatabase(db2);
+ pool->returnDatabase(db3);
+ pool->returnDatabase(db4);
+
+ return NULL;
+}
+
+TEST_BEGIN;
+
+ConnectionPool pool;
+
+Database *db1 = (Database*)1;
+Database *db2 = (Database*)2;
+Database *db3 = (Database*)3;
+Database *db4 = (Database*)4;
+
+pool.addDatabase(db1);
+pool.addDatabase(db2);
+pool.addDatabase(db3);
+pool.addDatabase(db4);
+
+TEST_TRUE(pool.testFree(db1), "Testing if db1 is free.");
+TEST_TRUE(pool.testFree(db2), "Testing if db2 is free.");
+TEST_TRUE(pool.testFree(db3), "Testing if db3 is free.");
+TEST_TRUE(pool.testFree(db4), "Testing if db4 is free.");
+TEST_EQUAL(pool.numFreeDatabases(), 4, "Testing number of free databases.");
+
+Database *b_db1 = pool.borrowDatabase();
+TEST_FALSE(pool.testFree(b_db1), "Testing if borrowed db is free.");
+
+Database *b_db2 = pool.borrowDatabase();
+TEST_NOTEQUAL(b_db1, b_db2, "Testing if borrowed db is unique.");
+
+pool.returnDatabase(b_db1);
+TEST_TRUE(pool.testFree(b_db1), "Testing if returned db is free.");
+pool.returnDatabase(b_db2);
+
+TEST_EQUAL(pool.numFreeDatabases(), 4, "Testing number of free databases.");
+
+pthread_attr_t attr;
+pthread_t tid;
+pthread_attr_init(&attr);
+pthread_create(&tid, &attr, thread_run, &pool);
+
+while(pool.numFreeDatabases() > 0) { usleep(10); }
+
+Database *b_db3 = pool.borrowDatabase();
+TEST_FALSE(pool.testFree(b_db3), "Testing if returned db is free (semaphore test).");
+pool.returnDatabase(db3);
+
+pthread_join(tid, NULL);
+pthread_attr_destroy(&attr);
+
+TEST_EQUAL(pool.numFreeDatabases(), 4, "Testing if all database are now available again");
+
+{
+ TEST_EQUAL(pool.numFreeDatabases(), 4, "Testing if autoborrower has not yet borrowed a db.");
+ AutoBorrower b(pool);
+ TEST_EQUAL(pool.numFreeDatabases(), 3, "Testing if autoborrower has borrowed a db.");
+ TEST_FALSE(pool.testFree(b.db()), "Testing if the autoborrowed db is actually taken.");
+}
+TEST_EQUAL(pool.numFreeDatabases(), 4, "Testing if autoborrower has returned the db.");
+
+TEST_END;
+
+#endif/*TEST_CONNECTIONPOOL*/
diff --git a/server/src/connectionpool.h b/server/src/connectionpool.h
new file mode 100644
index 0000000..548d76a
--- /dev/null
+++ b/server/src/connectionpool.h
@@ -0,0 +1,70 @@
+/* -*- 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"
+
+class Database;
+
+class ConnectionPool {
+public:
+ ConnectionPool();
+
+ void addDatabase(Database *db);
+ void removeDatabase(Database *db);
+
+ bool testFree(Database *db);
+ int numFreeDatabases();
+
+ Database *borrowDatabase();
+ void returnDatabase(Database *db);
+
+private:
+ Semaphore semaphore;
+ Mutex mutex;
+ std::list<Database *> activedbs;
+ std::list<Database *> passivedbs;
+};
+
+class AutoBorrower {
+public:
+ AutoBorrower(ConnectionPool &pool);
+ ~AutoBorrower();
+
+ Database *db();
+
+private:
+ ConnectionPool &pool;
+ Database *_db;
+};
+
+#endif/*__PRACRO_CONNECTIONPOOL_H__*/
diff --git a/server/src/semaphore.cc b/server/src/semaphore.cc
new file mode 100644
index 0000000..e5f1f31
--- /dev/null
+++ b/server/src/semaphore.cc
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * semaphore.cc
+ *
+ * Sat Oct 8 17:44:13 CEST 2005
+ * Copyright 2005 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.
+ */
+#include "semaphore.h"
+
+Semaphore::Semaphore()
+{
+ sem_init(&semaphore, 0, 0);
+}
+
+Semaphore::~Semaphore()
+{
+ sem_destroy(&semaphore);
+}
+
+void Semaphore::post()
+{
+ sem_post(&semaphore);
+}
+
+void Semaphore::wait()
+{
+ sem_wait(&semaphore);
+}
diff --git a/server/src/semaphore.h b/server/src/semaphore.h
new file mode 100644
index 0000000..72121f9
--- /dev/null
+++ b/server/src/semaphore.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * semaphore.h
+ *
+ * Sat Oct 8 17:44:13 CEST 2005
+ * Copyright 2005 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_SEMAPHORE_H__
+#define __PRACRO_SEMAPHORE_H__
+
+#include </usr/include/semaphore.h>
+
+class Semaphore {
+public:
+ Semaphore();
+ ~Semaphore();
+
+ void post();
+ void wait();
+
+private:
+ sem_t semaphore;
+};
+
+#endif/*__PRACRO_SEMAPHORE_H__*/