Index: src/Fragmentation/Automation/FragmentScheduler.cpp
===================================================================
--- src/Fragmentation/Automation/FragmentScheduler.cpp	(revision 402bde72b40b66cbc74451c852e07802a12af199)
+++ src/Fragmentation/Automation/FragmentScheduler.cpp	(revision 778abb8ccf156d1308e41e6fad137c7987dc7c8f)
@@ -57,11 +57,17 @@
   ),
   result(JobId::NoJob),
+  choice(NoOperation),
   Exitflag(OkFlag)
 {
   Info info(__FUNCTION__);
 
-  initiateWorkerSocket();
+  // only initiate socket if jobs are already present
+  if (JobsQueue.isJobPresent()) {
+    LOG(1, "Listening for workers on port " << workerport << ".");
+    initiateWorkerSocket();
+  }
 
   initiateControllerSocket();
+  LOG(1, "Listening for controller on port " << controllerport << ".");
 }
 
@@ -117,7 +123,4 @@
         boost::asio::placeholders::error, conn));
 
-      // Start an accept operation for a new Connection only when there
-      // are still jobs present otherwise we quit.
-      initiateWorkerSocket();
     } else {
       // send the static NoJob
@@ -139,4 +142,9 @@
     ELOG(0, e.message());
   }
+
+  // Start an accept operation for a new Connection only when there
+  // are still jobs present
+  if (JobsQueue.isJobPresent())
+    initiateWorkerSocket();
 }
 
@@ -169,15 +177,15 @@
 {
   Info info(__FUNCTION__);
-  // nothing to do
   LOG(1, "INFO: Received result for job #" << result.getId() << " ...");
-  // and push into queue
   ASSERT(result.getId() != (JobId_t)JobId::NoJob,
       "FragmentScheduler::handle_ReceiveResultFromWorker() - result received has NoJob id.");
   ASSERT(result.getId() != (JobId_t)JobId::IllegalJob,
       "FragmentScheduler::handle_ReceiveResultFromWorker() - result received has IllegalJob id.");
+  // place id into expected
   if ((result.getId() != (JobId_t)JobId::NoJob) && (result.getId() != (JobId_t)JobId::IllegalJob))
     JobsQueue.pushResult(result);
   // erase result
   result = FragmentResult(JobId::NoJob);
+  LOG(1, "INFO: JobsQueue has " << JobsQueue.getDoneJobs() << " results.");
 }
 
@@ -196,21 +204,7 @@
   if (!e)
   {
-    if (JobsQueue.isJobPresent() || !JobsQueue.getDoneJobs()) {
-      // The connection::async_write() function will automatically
-      // serialize the data structure for us.
-      LOG(1, "INFO: Receiving bunch of jobs from a controller ...");
-      conn->async_read(jobs,
-        boost::bind(&FragmentScheduler::handle_ReceiveJobs, this,
-        boost::asio::placeholders::error, conn));
-    } else {
-      // we just give a status report ...
-      // first update number
-      doneJobs = JobsQueue.getDoneJobs();
-      // now we accept connections to check for state of calculations
-      LOG(1, "INFO: Sending state of results to controller ...");
-      conn->async_write(doneJobs,
-        boost::bind(&FragmentScheduler::handle_CheckResultState, this,
-        boost::asio::placeholders::error, conn));
-    }
+    conn->async_read(choice,
+      boost::bind(&FragmentScheduler::handle_ReadChoice, this,
+      boost::asio::placeholders::error, conn));
   }
   else
@@ -224,6 +218,81 @@
 }
 
+/** Controller callback function to read the choice for next operation.
+ *
+ * \param e error code if something went wrong
+ * \param conn reference with the connection
+ */
+void FragmentScheduler::handle_ReadChoice(const boost::system::error_code& e, connection_ptr conn)
+{
+  Info info(__FUNCTION__);
+  if (!e)
+  {
+    // switch over the desired choice read previously
+    switch(choice) {
+    case NoOperation:
+    {
+      ELOG(1, "FragmentScheduler::handle_ReadChoice() - called with NoOperation.");
+      break;
+    }
+    case ReceiveJobs:
+      {
+        // The connection::async_write() function will automatically
+        // serialize the data structure for us.
+        LOG(1, "INFO: Receiving bunch of jobs from a controller ...");
+        conn->async_read(jobs,
+          boost::bind(&FragmentScheduler::handle_ReceiveJobs, this,
+          boost::asio::placeholders::error, conn));
+        break;
+      }
+    case CheckState:
+    {
+      // first update number
+      doneJobs = JobsQueue.getDoneJobs();
+      // now we accept connections to check for state of calculations
+      LOG(1, "INFO: Sending state that "+toString(doneJobs)+" jobs are done to controller ...");
+      conn->async_write(doneJobs,
+        boost::bind(&FragmentScheduler::handle_CheckResultState, this,
+        boost::asio::placeholders::error, conn));
+
+      initiateControllerSocket();
+      break;
+    }
+    case SendResults:
+    {
+      const std::vector<FragmentResult> results = JobsQueue.getAllResults();
+      // ... or we give the results
+      LOG(1, "INFO: Sending "+toString(results.size())+" results to controller ...");
+      conn->async_write(results,
+        boost::bind(&FragmentScheduler::handle_SendResults, this,
+        boost::asio::placeholders::error, conn));
+
+      initiateControllerSocket();
+      break;
+    }
+    default:
+      Exitflag = ControllerErrorFlag;
+      ELOG(1, "FragmentScheduler::handle_ReadChoice() - called with no valid choice.");
+      break;
+    }
+    // restore NoOperation choice such that choice is not read twice
+    choice = NoOperation;
+
+  }
+  else
+  {
+    // An error occurred. Log it and return. Since we are not starting a new
+    // accept operation the io_service will run out of work to do and the
+    // server will exit.
+    Exitflag = ControllerErrorFlag;
+    ELOG(0, e.message());
+  }
+}
+
 /** Controller callback function when job has been sent.
  *
+ * We check here whether the worker socket is accepting, if there
+ * have been no jobs we re-activate it, as it is shut down after
+ * last job.
+ *
  * \param e error code if something went wrong
  * \param conn reference with the connection
@@ -232,12 +301,14 @@
 {
   Info info(__FUNCTION__);
+  bool initiateSocket = !JobsQueue.isJobPresent();
+
   // jobs are received, hence place in JobsQueue
   if (!jobs.empty()) {
     LOG(1, "INFO: Pushing " << jobs.size() << " jobs into queue.");
     JobsQueue.pushJobs(jobs);
-  }
-  // launch new acceptor of queue has been filled/is full
-  if (JobsQueue.isJobPresent()) {
-    // Start an accept operation for a new Connection.
+    // initiate socket if we had no jobs before
+    if (initiateSocket)
+      initiateWorkerSocket();
+    // launch new acceptor of queue has been filled/is full
     initiateControllerSocket();
   } else {
@@ -246,4 +317,5 @@
 
   jobs.clear();
+
 }
 
@@ -259,2 +331,15 @@
   LOG(1, "INFO: Sent that " << doneJobs << " jobs are done.");
 }
+
+/** Controller callback function when result has been received.
+ *
+ * \param e error code if something went wrong
+ * \param conn reference with the connection
+ */
+void FragmentScheduler::handle_SendResults(const boost::system::error_code& e, connection_ptr conn)
+{
+  Info info(__FUNCTION__);
+  // do nothing
+  LOG(1, "INFO: Results have been sent.");
+}
+
