Index: trunk/FACT++/src/EventBuilder.h
===================================================================
--- trunk/FACT++/src/EventBuilder.h	(revision 16379)
+++ trunk/FACT++/src/EventBuilder.h	(revision 16380)
@@ -3,4 +3,7 @@
 
 #include "FAD.h"
+
+#include <array>
+#include <forward_list>
 
 /* global variables; 
@@ -32,9 +35,11 @@
 enum CloseRequest_t
 {
-    kRequestNone = 0,
-    kRequestManual = 1,
-    kRequestTimeout = 2,
-    kRequestConnectionChange = 4,
-    kRequestEventCheckFailed = 8
+    kRequestNone             =    0,
+    kRequestManual           = 1<<1,
+    kRequestTimeout          = 1<<2,
+    kRequestConnectionChange = 1<<3,
+    kRequestEventCheckFailed = 1<<4,
+    kRequestMaxEvtsReached   = 1<<5,
+    kRequestMaxTimeReached   = 1<<6
 };
 
@@ -58,9 +63,9 @@
 
     FileStatus_t fileStat;
-    int closeRequest;
 
     std::shared_ptr<DrsCalibration> calib;
+    std::list<std::array<int16_t,1440>> prevStart; // History for start cells of previous events (for step calibration)
 
-    RUN_CTRL2() : runId(-1), lastTime(0), lastEvt(0), maxEvt(1<<31), fileStat(kFileNotYetOpen), closeRequest(kRequestNone)
+    RUN_CTRL2() : runId(-1), lastTime(0), lastEvt(0), maxEvt(1<<31), fileStat(kFileNotYetOpen)
     {
         // runId   = -1;
@@ -74,14 +79,32 @@
 };
 
+#define MAX_HEAD_MEM (NBOARDS * sizeof(PEVNT_HEADER))
+#define MAX_TOT_MEM (sizeof(EVENT) + (NPIX+NTMARK)*1024*2 + MAX_HEAD_MEM)
+
+namespace Memory
+{
+    extern uint64_t inuse;
+    extern uint64_t allocated;
+
+    extern uint64_t max_inuse;
+
+    extern std::mutex mtx;
+
+    extern std::forward_list<void*> memory;
+
+    extern void *malloc();
+    extern void  free(void *mem);
+};
+
 struct EVT_CTRL2
 {
-    int64_t   runNum;
-    uint32_t  evNum;
+    uint32_t  runNum;  // header->runnumber;
+    uint32_t  evNum;   // header->fad_evt_counter
 
-    uint32_t  trgNum;
-    uint32_t  trgTyp;
+    uint32_t  trgNum;  // header->trigger_id
+    uint32_t  trgTyp;  // header->trigger_type
     uint32_t  fadLen;
 
-    uint32_t  nBoard;
+    uint16_t  nBoard;
     int16_t   board[NBOARDS];
 
@@ -92,20 +115,35 @@
     uint8_t   Errors[4];
 
-    std::shared_ptr<PEVNT_HEADER> FADhead;
-    EVENT *fEvent;
+    PEVNT_HEADER *FADhead; // Pointer to the whole allocated memory
+    EVENT        *fEvent;  // Pointer to the event data itself
+    PEVNT_HEADER *header;  // Pointer to a valid header within FADhead
+
+    bool reportMem;        // initMemory has reported no memory once (set outside of class)
+    int closeRequest;
 
     std::shared_ptr<RUN_CTRL2> runCtrl;
 
-    EVT_CTRL2(std::shared_ptr<RUN_CTRL2> run=std::shared_ptr<RUN_CTRL2>()) : runNum(-1), runCtrl(run)
+    // Be carefull with this constructor... writeEvt can seg fault
+    // it gets an empty runCtrl
+    EVT_CTRL2() : nBoard(0), FADhead(0), header(0), reportMem(false), closeRequest(kRequestNone)
     {
-        Errors[0] = 0;
-        Errors[1] = 0;
-        Errors[2] = 0;
-        Errors[3] = 0;
+        //flag all boards as unused
+        std::fill(board, board+NBOARDS, -1);
+    }
+    /*
+    EVT_CTRL2(CloseRequest_t req) : nBoard(0), FADhead(0), header(0), reportMem(false), closeRequest(req), runCtrl(new RUN_CTRL2)
+    {
+        //flag all boards as unused
+        std::fill(board, board+NBOARDS, -1);
+        }*/
 
+    EVT_CTRL2(int req, const std::shared_ptr<RUN_CTRL2> &run) : nBoard(0), FADhead(0), header(0), reportMem(false), closeRequest(req), runCtrl(run)
+    {
         //flag all boards as unused
-        nBoard = 0;
-        for (int b=0; b<NBOARDS; b++)
-            board[b] = -1;
+        std::fill(board, board+NBOARDS, -1);
+    }
+    ~EVT_CTRL2()
+    {
+        Memory::free(FADhead);
     }
 
@@ -119,28 +157,30 @@
         rh.RunUsec = time.tv_usec;
 
-        memcpy(rh.FADhead, FADhead.get(), NBOARDS*sizeof(PEVNT_HEADER));
+        memcpy(rh.FADhead, FADhead, NBOARDS*sizeof(PEVNT_HEADER));
 
         return rh;
     }
 
-    void initEvent(const std::shared_ptr<PEVNT_HEADER> &mem)
+    bool valid() const { return header; }
+
+    bool initMemory()
     {
-        FADhead = mem;
-        fEvent  = reinterpret_cast<EVENT*>(mem.get()+NBOARDS);
+        // We have a valid entry, but no memory has yet been allocated
+        if (FADhead)
+            return true;
+
+        FADhead = (PEVNT_HEADER*)Memory::malloc();
+        if (!FADhead)
+            return false;
+
+        fEvent = reinterpret_cast<EVENT*>(FADhead+NBOARDS);
 
         memset(fEvent->Adc_Data, 0, (NPIX+NTMARK)*2*nRoi);
 
-        //flag all pixels as unused
-        for (int k = 0; k < NPIX; k++)
-            fEvent->StartPix[k] = -1;
+        //flag all pixels as unused, flag all TMark as unused
+        std::fill(fEvent->StartPix, fEvent->StartPix+NPIX,   -1);
+        std::fill(fEvent->StartTM,  fEvent->StartTM +NTMARK, -1);
 
-        //flag all TMark as unused
-        for (int k = 0; k < NTMARK; k++)
-            fEvent->StartTM[k] = -1;
-
-        fEvent->NumBoards   = 0;
         fEvent->SoftTrig    = 0;
-        fEvent->PCTime      = time.tv_sec;
-        fEvent->PCUsec      = time.tv_usec;
         fEvent->Roi         = nRoi;
         fEvent->RoiTM       = nRoiTM;
@@ -148,4 +188,6 @@
         fEvent->TriggerNum  = trgNum;
         fEvent->TriggerType = trgTyp;
+
+        return true;
     }
 };
