From b8a6eb573c1992d41393cec87d1ac8d6fb3a6972 Mon Sep 17 00:00:00 2001
From: deva <deva>
Date: Fri, 13 Nov 2009 15:15:00 +0000
Subject: Make session system more robust. Make server termination show live
 sessions and issue a warning.

---
 server/src/server.cc | 44 +++++++++++++++++++++++++++++++-------------
 1 file changed, 31 insertions(+), 13 deletions(-)

(limited to 'server')

diff --git a/server/src/server.cc b/server/src/server.cc
index a3c7667..1b2a05c 100644
--- a/server/src/server.cc
+++ b/server/src/server.cc
@@ -337,14 +337,16 @@ static std::string handleConnection(const char *buf, size_t size, struct conn_t
   PRACRO_DEBUG(server, "Read %d bytes from network\n", size);
 
   std::string res;
-  if(parser.parse(buf, size)) {
-    PRACRO_DEBUG(server, "Got complete XML document, %d bytes in current buffer.\n", size);
-
-    res = handleTransaction(&transaction, pentominos_socket,
-                                        *conn->db, *journalwriter, macrolist, templatelist);
-  } else {
-    PRACRO_ERR(server, "Failed to parse data!\n");
-    res = error_box(xml_encode("XML Parse error."));
+  if(size) {
+    if(parser.parse(buf, size)) {
+      PRACRO_DEBUG(server, "Got complete XML document, %d bytes in current buffer.\n", size);
+      
+      res = handleTransaction(&transaction, pentominos_socket,
+                              *conn->db, *journalwriter, macrolist, templatelist);
+    } else {
+      PRACRO_ERR(server, "Failed to parse data!\n");
+      res = error_box(xml_encode("XML Parse error."));
+    }
   }
 
   if(commitsession) {
@@ -358,10 +360,16 @@ static std::string handleConnection(const char *buf, size_t size, struct conn_t
   return res;
 }
 
-static sessionid_t newSessionID()
+static sessionid_t newSessionID(struct conn_t *conn)
 {
-  static volatile sessionid_t sessionid = 0;
-  return sessionid++;
+  sessionid_t sid;
+  conn->mutex.lock();
+  // Find a random session id that is not in use.
+  do {
+    sid = rand();
+  } while(conn->sessions.find(sid) != conn->sessions.end());
+  conn->mutex.unlock();
+  return sid;
 }
 
 static int handle_request(void *cls,
@@ -383,7 +391,7 @@ static int handle_request(void *cls,
   bool commitsession = false;
   
   const char *sessionids = MHD_lookup_connection_value(con, MHD_HEADER_KIND, "SessionID");
-  if(sessionids == NULL) sessionid = newSessionID();
+  if(sessionids == NULL) sessionid = newSessionID(conn);
   else sessionid = atoll(sessionids);
   printf("SessionID: %llu\n", sessionid);
 
@@ -452,6 +460,9 @@ E0OPPYamkDI/+6Hx2KECQHF9xV1XatyXuFmfRAInK2BtfGY5UIvJaLxVD3Z1+i6q\n\
 extern bool pracro_is_running;
 void server()
 {
+  srand(time(NULL));
+
+  bool forceshutdown = false;
   port_t port = Conf::server_port;
 
   PRACRO_DEBUG(server, "Server running on port %d.\n", port);
@@ -481,9 +492,16 @@ void server()
     PRACRO_ERR(server, "Failed to initialise MHD_start_daemon!\n");
     return;
   }
-
+ again:
   while(pracro_is_running) sleep(1);
 
+  if(!forceshutdown && conn.sessions.size() != 0) {
+    PRACRO_ERR_LOG(server, "There are %d live sesions."
+                   " Kill again to force shutdown.\n", conn.sessions.size());
+    pracro_is_running = true;
+    forceshutdown = true;
+    goto again;
+  }
   delete conn.db;
 
   MHD_stop_daemon(d);
-- 
cgit v1.2.3