summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeva <deva>2009-11-12 10:02:54 +0000
committerdeva <deva>2009-11-12 10:02:54 +0000
commit93500a9656dffde57ab32410642c2dd74098b9f8 (patch)
tree92cc783992ec34b495f0f08354b435fa786e4454
parent484d5c2b4dcf59f88093614903c6da5bec54ebda (diff)
Make database connection shared among threads and make is thread safe.
-rw-r--r--server/src/Makefile.am5
-rw-r--r--server/src/database.h31
-rw-r--r--server/src/mutex.cc57
-rw-r--r--server/src/mutex.h45
-rw-r--r--server/src/server.cc23
5 files changed, 148 insertions, 13 deletions
diff --git a/server/src/Makefile.am b/server/src/Makefile.am
index 3da4f19..a753ee7 100644
--- a/server/src/Makefile.am
+++ b/server/src/Makefile.am
@@ -23,6 +23,7 @@ pracrod_SOURCES = \
macroheaderparser.cc \
macrolist.cc \
macroparser.cc \
+ mutex.cc \
pracrodao.cc \
pracrodaopgsql.cc \
pracrodaotest.cc \
@@ -58,6 +59,7 @@ macrotool_SOURCES = \
macrotool_fieldnames.cc \
macrotool_filehandler.cc \
macrotool_util.cc \
+ mutex.cc \
pracrodao.cc \
pracrodaopgsql.cc \
pracrodaotest.cc \
@@ -88,6 +90,7 @@ EXTRA_DIST = \
macrotool_fieldnames.h \
macrotool_filehandler.h \
macrotool_util.h \
+ mutex.h \
pracrodao.h \
pracrodaopgsql.h \
pracrodaotest.h \
@@ -140,7 +143,7 @@ BASICFLAGS = -I.. -DHAVE_CONFIG_H $(CONFIG_CXXFLAGS) $(CONFIG_LIBS)
PARSERFILES = saxparser.cc
PARSERFLAGS = -lexpat
-DBFILES = database.cc pracrodao.cc pracrodaopgsql.cc pracrodaotest.cc
+DBFILES = database.cc pracrodao.cc pracrodaopgsql.cc pracrodaotest.cc mutex.cc
DBFLAGS = $(PQXX_LIBS) $(PQXX_CXXFLAGS)
test: $(TESTFILES)
diff --git a/server/src/database.h b/server/src/database.h
index 396dda4..f253ba5 100644
--- a/server/src/database.h
+++ b/server/src/database.h
@@ -32,7 +32,7 @@
#include "pracrodao.h"
#include "transaction.h"
#include "template.h"
-
+#include "mutex.h"
#include "debug.h"
class Database {
@@ -42,22 +42,31 @@ public:
// Make a commit to the db
void commitTransaction(std::string user, std::string patientid, Macro &macro, Fields &fields, time_t now = time(NULL)) {
+ if(!dao) return;
+ mutex.lock();
PRACRO_DEBUG(db, "%s, %s, %s,...\n", user.c_str(), patientid.c_str(), macro.attributes["name"].c_str());
- if(dao) dao->commitTransaction(user, patientid, macro, fields, now);
+ dao->commitTransaction(user, patientid, macro, fields, now);
+ mutex.unlock();
}
// Get a list of values from the db
Values getValues(std::string patientid, Fieldnames &fieldnames, time_t oldest = 0) {
+ if(!dao) return Values();
+ mutex.lock();
PRACRO_DEBUG(db, "%s, <%u fieldnames>, %ld\n", patientid.c_str(), fieldnames.size(), oldest);
- if(dao) return dao->getLatestValues(patientid, NULL, fieldnames, oldest);
- else return Values();
+ Values values = dao->getLatestValues(patientid, NULL, fieldnames, oldest);
+ mutex.unlock();
+ return values;
}
// Check if a macro has been committed.
bool checkMacro(std::string patientid, std::string macro, time_t oldest = 0) {
PRACRO_DEBUG(db, "%s, %s, %ld\n", patientid.c_str(), macro.c_str(), oldest);
if(!dao) return false;
- return dao->nrOfCommits(patientid, macro, oldest) > 0;
+ mutex.lock();
+ bool res = dao->nrOfCommits(patientid, macro, oldest) > 0;
+ mutex.unlock();
+ return res;
}
// Get latest resume of a given macro
@@ -66,7 +75,9 @@ public:
if(!dao) return "";
Fieldnames fn;
fn.push_back("journal.resume");
+ mutex.lock();
Values v = dao->getLatestValues(patientid, &macro, fn, oldest);
+ mutex.unlock();
Values::iterator i = v.find("journal.resume");
if(i != v.end()) return i->second.value;
else return "";
@@ -75,13 +86,17 @@ public:
void addFieldname(std::string name, std::string description)
{
if(!dao) return;
+ mutex.lock();
dao->addFieldname(name, description);
+ mutex.unlock();
}
void delFieldname(std::string name)
{
if(!dao) return;
+ mutex.lock();
dao->delFieldname(name);
+ mutex.unlock();
}
std::vector<Fieldname> getFieldnames()
@@ -90,11 +105,15 @@ public:
std::vector<Fieldname> fieldnames;
return fieldnames;
}
- return dao->getFieldnames();
+ mutex.lock();
+ std::vector<Fieldname> fieldnames = dao->getFieldnames();
+ mutex.unlock();
+ return fieldnames;
}
private:
PracroDAO *dao;
+ Mutex mutex;
};
#endif/*__PRACRO_DATABASE_H__*/
diff --git a/server/src/mutex.cc b/server/src/mutex.cc
new file mode 100644
index 0000000..2cc75cc
--- /dev/null
+++ b/server/src/mutex.cc
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * mutex.cc
+ *
+ * Thu Nov 12 10:51:32 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 "mutex.h"
+
+Mutex::Mutex()
+{
+ pthread_mutex_init (&mutex, NULL);
+}
+
+Mutex::~Mutex()
+{
+ pthread_mutex_destroy(&mutex);
+}
+
+void Mutex::lock()
+{
+ pthread_mutex_lock( &mutex );
+}
+
+void Mutex::unlock()
+{
+ pthread_mutex_unlock( &mutex );
+}
+
+#ifdef TEST_MUTEX
+
+int main()
+{
+ return 0;
+}
+
+#endif/*TEST_MUTEX*/
diff --git a/server/src/mutex.h b/server/src/mutex.h
new file mode 100644
index 0000000..8b35042
--- /dev/null
+++ b/server/src/mutex.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * mutex.h
+ *
+ * Thu Nov 12 10:51:32 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_MUTEX_H__
+#define __PRACRO_MUTEX_H__
+
+#include <pthread.h>
+
+class Mutex {
+public:
+ Mutex();
+ ~Mutex();
+
+ void lock();
+ void unlock();
+
+private:
+ pthread_mutex_t mutex;
+};
+
+#endif/*__PRACRO_MUTEX_H__*/
diff --git a/server/src/server.cc b/server/src/server.cc
index d9b28a9..67ae74d 100644
--- a/server/src/server.cc
+++ b/server/src/server.cc
@@ -60,6 +60,11 @@
#include "templatelist.h"
#include "versionstr.h"
+struct conn_t {
+ Database *db;
+
+};
+
static std::string error_box(std::string message)
{
std::string errorbox =
@@ -296,7 +301,7 @@ static std::string handleTransaction(Transaction *transaction,
}
-static std::string handleConnection(char *buf, size_t size)
+static std::string handleConnection(char *buf, size_t size, struct conn_t *conn)
{
if(size == 0)
return error_box(xml_encode("Empty document received."));
@@ -306,8 +311,6 @@ static std::string handleConnection(char *buf, size_t size)
pentominos_socket.connect(Conf::pentominos_addr, Conf::pentominos_port);
#endif/*WITHOUT_PENTOMINOS*/
- Database db(Conf::database_backend, Conf::database_addr, "", Conf::database_user, Conf::database_passwd, "");
-
JournalWriter journalwriter(Conf::journal_commit_addr.c_str(), Conf::journal_commit_port);
MacroList macrolist(Conf::xml_basedir + "/macros");
@@ -322,7 +325,7 @@ static std::string handleConnection(char *buf, size_t size)
PRACRO_DEBUG(server, "Got complete XML document, %d bytes in current buffer.\n", size);
std::string res = handleTransaction(&transaction, pentominos_socket,
- db, journalwriter, macrolist, templatelist);
+ *conn->db, journalwriter, macrolist, templatelist);
journalwriter.commit();
return res;
@@ -341,12 +344,14 @@ static int handle_request(void *cls,
unsigned int *data_size,
void **ptr)
{
+ struct conn_t *conn = (struct conn_t*)cls;
+
PRACRO_DEBUG(httpd,
"handle_request(url=\"%s\", method=\"%s\","
" version=\"%s\", data_size=\"%d\")\n",
url, method, version, *data_size);
- std::string reply = handleConnection((char*)data, *data_size);
+ std::string reply = handleConnection((char*)data, *data_size, conn);
struct MHD_Response *rsp;
rsp = MHD_create_response_from_data(reply.length(), (char*)reply.c_str(), MHD_NO, MHD_YES);
@@ -404,6 +409,10 @@ void server()
PRACRO_DEBUG(server, "Server running on port %d.\n", port);
+ struct conn_t conn;
+ conn.db = new Database(Conf::database_backend, Conf::database_addr,
+ "", Conf::database_user, Conf::database_passwd, "");
+
struct MHD_Daemon *d;
d = MHD_start_daemon(MHD_USE_DEBUG
| MHD_USE_SELECT_INTERNALLY
@@ -412,7 +421,7 @@ void server()
,
port,
NULL, NULL,
- handle_request, NULL,
+ handle_request, &conn,
MHD_OPTION_NOTIFY_COMPLETED, NULL, NULL,
// MHD_OPTION_CONNECTION_LIMIT, 42,
MHD_OPTION_HTTPS_MEM_KEY, KEY,
@@ -428,6 +437,8 @@ void server()
while(pracro_is_running) sleep(1);
+ delete conn.db;
+
MHD_stop_daemon(d);
PRACRO_DEBUG(server, "Server gracefully shut down.\n");