summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2011-11-28 15:03:17 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2011-11-28 15:03:17 +0100
commit2a89f766b3c4917001de03a06bfbecb1ce25675f (patch)
tree03f2e68488a5dad0619651c771912e8759fddfdc
parentdd1fb6e16ff777d3e098076d1015c6c565b51bb7 (diff)
Use one-thread-per-connection and fix up Session locking.
-rw-r--r--server/src/admin_connection.cc12
-rw-r--r--server/src/client_connection.cc15
-rw-r--r--server/src/client_connection.h7
-rw-r--r--server/src/httpd.cc9
-rw-r--r--server/src/session.cc23
-rw-r--r--server/src/session.h12
6 files changed, 53 insertions, 25 deletions
diff --git a/server/src/admin_connection.cc b/server/src/admin_connection.cc
index 6ad7642..60c09d0 100644
--- a/server/src/admin_connection.cc
+++ b/server/src/admin_connection.cc
@@ -36,7 +36,11 @@
static std::string admin_sessionunlock(Environment &env, std::string id)
{
- Session *session = env.sessions.session(id);
+ // NOTE: Returned session is returned in locked state!
+ Session *session = NULL;
+ SessionAutounlock l(&session);
+
+ session = env.sessions.lockedSession(id);
if(session) {
if(session->isReadonly()) {
env.sessions.deleteSession(id);
@@ -56,8 +60,10 @@ static std::string admin_listactivesessions(Environment &env)
std::vector<std::string> act = env.sessions.activeSessions();
std::vector<std::string>::iterator i = act.begin();
while(i != act.end()) {
- Session *s = env.sessions.session(*i);
- SessionAutolock lock(*s);
+ // NOTE: Returned session is returned in locked state!
+ Session *s = NULL;
+ SessionAutounlock l(&s);
+ s = env.sessions.lockedSession(*i);
str += "Session " + *i + ": "+s->templ+" on "+s->patientid+" "+
std::string(s->idle()?"[idle]":"[active]")+"\n";
i++;
diff --git a/server/src/client_connection.cc b/server/src/client_connection.cc
index fe55efc..075dc46 100644
--- a/server/src/client_connection.cc
+++ b/server/src/client_connection.cc
@@ -44,7 +44,7 @@ static std::string error_box(std::string message)
static bool did_commit = false;
#endif
-ClientConnection::ClientConnection(Environment &e, headers_t &headers,
+ClientConnection::ClientConnection(Environment &e, headers_t headers,
headers_t args, std::string uri)
: env(e), parser(&transaction)
{
@@ -154,17 +154,22 @@ bool ClientConnection::handle(const char *data, size_t size)
}
Session *session = NULL;
+ SessionAutounlock l(&session);
+
try {
if(sessionid == "") {
// Create new session
- session = env.sessions.newSession(patientid, templ);
+ // NOTE: New session is returned in locked state!
+ session = env.sessions.newLockedSession(patientid, templ);
} else {
// Attach to old session
- session = env.sessions.session(sessionid);
+ // NOTE: Returned session is returned in locked state!
+ session = env.sessions.lockedSession(sessionid);
// Session didn't exist - create a new one anyway.
if(session == NULL) {
- session = env.sessions.newSession(patientid, templ);
+ // NOTE: New session is returned in locked state!
+ session = env.sessions.newLockedSession(patientid, templ);
}
}
} catch(Sessions::SessionAlreadyActive &e) {
@@ -201,7 +206,7 @@ bool ClientConnection::handle(const char *data, size_t size)
parser_complete = true;
{
- SessionAutolock lock(*session);
+ //SessionAutolock lock(session);
response = handleTransaction(request, transaction, env, *session);
}
diff --git a/server/src/client_connection.h b/server/src/client_connection.h
index b811b7f..e64dcad 100644
--- a/server/src/client_connection.h
+++ b/server/src/client_connection.h
@@ -40,7 +40,12 @@ class Session;
class ClientConnection : public Connection {
public:
- ClientConnection(Environment &e, headers_t &headers,
+ /**
+ * URI: course/template/macro
+ * Params: petientid, sessionid and statechange (commit, nocommit or discard)
+ * Headers are currently not used.
+ */
+ ClientConnection(Environment &e, headers_t headers,
headers_t args, std::string uri);
~ClientConnection();
diff --git a/server/src/httpd.cc b/server/src/httpd.cc
index f7ad7f4..1c0575a 100644
--- a/server/src/httpd.cc
+++ b/server/src/httpd.cc
@@ -68,6 +68,11 @@ static int request_handler(void *cls,
unsigned int *data_size,
void **con_cls)
{
+ DEBUG(httpd, "request_handler: cls(%p) con(%p) url(%s) method(%s)"
+ " version(%s) *con_cls(%p)\n",
+ cls, con, url, method, version, *con_cls);
+ DEBUG(httpd, "request_handler: *data_size(%u) data:[%s]\n", *data_size, data);
+
int ret = MHD_YES;
Httpd *httpd = (Httpd*)cls;
@@ -176,7 +181,7 @@ Httpd::~Httpd()
void Httpd::listen(unsigned short int port,
unsigned int cn_limit, unsigned int cn_timeout)
{
- int flags = MHD_USE_DEBUG | MHD_USE_SELECT_INTERNALLY;
+ int flags = MHD_USE_DEBUG | MHD_USE_THREAD_PER_CONNECTION;
d = MHD_start_daemon(flags, port, NULL, NULL,
request_handler, this,
@@ -196,7 +201,7 @@ void Httpd::listen_ssl(unsigned short int port,
std::string key, std::string cert,
unsigned int cn_limit, unsigned int cn_timeout)
{
- int flags = MHD_USE_DEBUG | MHD_USE_SELECT_INTERNALLY | MHD_USE_SSL;
+ int flags = MHD_USE_DEBUG | MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL;
d_ssl = MHD_start_daemon(flags, port, NULL, NULL,
request_handler, this,
diff --git a/server/src/session.cc b/server/src/session.cc
index 8071d45..fcd138a 100644
--- a/server/src/session.cc
+++ b/server/src/session.cc
@@ -195,7 +195,7 @@ static bool fexists(const std::string &f)
return ret;
}
-Session *Sessions::newSession(std::string patientid, std::string templ)
+Session *Sessions::newLockedSession(std::string patientid, std::string templ)
throw(SessionAlreadyActive)
{
MutexAutolock lock(mutex);
@@ -209,6 +209,7 @@ Session *Sessions::newSession(std::string patientid, std::string templ)
DEBUG(session, "Patient/template matched session is already active.");
throw SessionAlreadyActive(session->id());
}
+ session->lock();
return session;
}
@@ -224,27 +225,33 @@ Session *Sessions::newSession(std::string patientid, std::string templ)
DEBUG(session, "Looked up session by id is already active.");
throw SessionAlreadyActive(session->id());
}
+ session->lock();
return session;
}
}
Session *session = new Session(env, "", patientid, templ);
sessions[session->id()] = session;
+ session->lock();
return session;
}
-Session *Sessions::session(std::string sessionid)
+Session *Sessions::lockedSession(std::string sessionid)
{
MutexAutolock lock(mutex);
- if(sessions.find(sessionid) != sessions.end())
- return sessions[sessionid];
+ if(sessions.find(sessionid) != sessions.end()) {
+ Session *s = sessions[sessionid];
+ s->lock();
+ return s;
+ }
std::string filename = getSessionFilename(Conf::session_path, sessionid);
if(fexists(filename)) {
SessionSerialiser ser(env, Conf::session_path);
Session *s = ser.load(sessionid);
sessions[s->id()] = s;
+ s->lock();
return s;
}
@@ -311,15 +318,15 @@ std::vector<std::string> Sessions::activeSessions()
return act;
}
-SessionAutolock::SessionAutolock(Session &s)
+SessionAutounlock::SessionAutounlock(Session **s)
: session(s)
{
- session.lock();
+ // session->lock();
}
-SessionAutolock::~SessionAutolock()
+SessionAutounlock::~SessionAutounlock()
{
- session.unlock();
+ if(*session) (*session)->unlock();
}
#ifdef TEST_SESSION
diff --git a/server/src/session.h b/server/src/session.h
index b5c31d7..4d1ed12 100644
--- a/server/src/session.h
+++ b/server/src/session.h
@@ -95,14 +95,14 @@ public:
* Create a new session, with a unique id. Insert it into the session list,
* and return its pointer.
*/
- Session *newSession(std::string patientid, std::string templ)
+ Session *newLockedSession(std::string patientid, std::string templ)
throw(SessionAlreadyActive);
/**
* Lookup session in session list. Returns the session or NULL if no session
* exists with that sessionid.
*/
- Session *session(std::string sessionid);
+ Session *lockedSession(std::string sessionid);
/**
* Remove session from the session list and return its pointer. It is up to
@@ -136,13 +136,13 @@ private:
Mutex mutex;
};
-class SessionAutolock {
+class SessionAutounlock {
public:
- SessionAutolock(Session &session);
- ~SessionAutolock();
+ SessionAutounlock(Session **session);
+ ~SessionAutounlock();
private:
- Session &session;
+ Session **session;
};
#endif/*__PRACRO_SESSION_H__*/