Index: /trunk/FACT++/src/EventBuilderWrapper.h
===================================================================
--- /trunk/FACT++/src/EventBuilderWrapper.h	(revision 15476)
+++ /trunk/FACT++/src/EventBuilderWrapper.h	(revision 15477)
@@ -54,5 +54,16 @@
 
 private:
-    boost::thread fThread;
+    boost::thread fThreadMain;
+    boost::thread fThreadDimQueue1;
+    boost::thread fThreadDimQueue2;
+
+    bool fThreadDimQueueStop;
+
+    deque<pair<Time,GUI_STAT>> fDimQueue1;
+    deque<tuple<Time,bool,FAD::EventHeader>> fDimQueue2;
+
+    mutex fMutexDimQueue1;
+    mutex fMutexDimQueue2;
+
 
     enum CommandStates_t // g_runStat
@@ -177,4 +188,5 @@
 public:
     EventBuilderWrapper(MessageImp &imp) : fMsg(imp),
+        fThreadDimQueueStop(false),
         fFileFormat(FAD::kNone), fMaxRun(0), fLastOpened(0), fLastClosed(0),
         fDimWriteStats  ("FAD_CONTROL", imp),
@@ -272,12 +284,20 @@
         for (size_t i=0; i<40; i++)
             ConnectSlot(i, tcp::endpoint());
-    }
+
+        fThreadDimQueue1 = boost::thread(boost::bind(&EventBuilderWrapper::SendStat, this));
+        fThreadDimQueue2 = boost::thread(boost::bind(&EventBuilderWrapper::ProcHeader, this));
+    }
+
     virtual ~EventBuilderWrapper()
     {
         Abort();
+        fThreadDimQueueStop = true;
 
         // FIXME: Used timed_join and abort afterwards
         //        What's the maximum time the eb need to abort?
-        fThread.join();
+        fThreadMain.join();
+        fThreadDimQueue1.join();
+        fThreadDimQueue2.join();
+
         //ffMsg.Info("EventBuilder stopped.");
 
@@ -318,5 +338,5 @@
     bool IsThreadRunning()
     {
-        return !fThread.timed_join(boost::posix_time::microseconds(0));
+        return !fThreadMain.timed_join(boost::posix_time::microseconds(0));
     }
 
@@ -351,5 +371,5 @@
         fMsg.Message("Starting EventBuilder thread");
 
-        fThread = boost::thread(StartEvtBuild);
+        fThreadMain = boost::thread(StartEvtBuild);
     }
     void ConnectSlot(unsigned int i, const tcp::endpoint &addr)
@@ -1241,7 +1261,29 @@
     }
 
+    void SendStat()
+    {
+        // Performance could be increased signaling the thread to wake up
+        while (!fThreadDimQueueStop)
+        {
+            if (fDimQueue1.size()==0)
+            {
+                usleep(1000);
+                continue;
+            }
+
+            fMutexDimQueue1.lock();
+            const pair<Time,GUI_STAT> stat = fDimQueue1.front();
+            fDimQueue1.pop_front();
+            fMutexDimQueue1.unlock();
+
+            fDimStatistics1.setData(&stat.second, sizeof(GUI_STAT));
+            fDimStatistics1.Update(stat.first);
+        }
+    }
+
     void factStat(const GUI_STAT &stat)
     {
-        fDimStatistics1.Update(stat);
+        const lock_guard<mutex> guard(fMutexDimQueue1);
+        fDimQueue1.push_back(make_pair(Time(), stat));
     }
 
@@ -1344,9 +1386,9 @@
 
     template<typename T, size_t N>
-    void Update(DimDescribedService &svc, const array<T, N> &data, int n=N)
+    void Update(DimDescribedService &svc, const array<T, N> &data, const Time &t=Time(), int n=N)
     {
 //        svc.setQuality(vec[40]<=vec[41]);
         svc.setData(const_cast<T*>(data.data()), sizeof(T)*n);
-        svc.Update();
+        svc.Update(t);
     }
 
@@ -1362,4 +1404,146 @@
     vector<uint> fNumConnected;
 
+    void ProcHeader()
+    {
+        // Performance could be increased signaling the thread to wake up
+        while (!fThreadDimQueueStop)
+        {
+            if (fDimQueue2.size()==0)
+            {
+                usleep(100);
+                continue;
+            }
+
+            fMutexDimQueue2.lock();
+            const auto dat = fDimQueue2.front();
+            fDimQueue2.pop_front();
+            fMutexDimQueue2.unlock();
+
+            const Time             &t = get<0>(dat);
+            const bool        changed = get<1>(dat);
+            const FAD::EventHeader &h = get<2>(dat);
+
+            const FAD::EventHeader old = fVecHeader[h.Id()];
+            fVecHeader[h.Id()] = h;
+
+            if (old.fVersion != h.fVersion || changed)
+            {
+                const array<uint16_t,42> ver = Compare(&fVecHeader[0], &fVecHeader[0].fVersion);
+
+                array<float,42> data;
+                for (int i=0; i<42; i++)
+                {
+                    ostringstream str;
+                    str << (ver[i]>>8) << '.' << (ver[i]&0xff);
+                    data[i] = stof(str.str());
+                }
+                Update(fDimFwVersion, data, t);
+            }
+
+            if (old.fRunNumber != h.fRunNumber || changed)
+            {
+                const array<uint32_t,42> run = Compare(&fVecHeader[0], &fVecHeader[0].fRunNumber);
+                fDimRunNumber.setData(&run[0], 42*sizeof(uint32_t));
+                fDimRunNumber.Update(t);
+            }
+
+            if (old.fTriggerGeneratorPrescaler != h.fTriggerGeneratorPrescaler || changed)
+            {
+                const array<uint16_t,42> pre = Compare(&fVecHeader[0], &fVecHeader[0].fTriggerGeneratorPrescaler);
+                fDimPrescaler.setData(&pre[0], 42*sizeof(uint16_t));
+                fDimPrescaler.Update(t);
+            }
+
+            if (old.fDNA != h.fDNA || changed)
+            {
+                const array<uint64_t,42> dna = Compare(&fVecHeader[0], &fVecHeader[0].fDNA);
+                Update(fDimDNA, dna, t, 40);
+            }
+
+            if (old.fStatus != h.fStatus || changed)
+            {
+                const array<uint16_t,42> sts = CompareBits(&fVecHeader[0], &fVecHeader[0].fStatus);
+                Update(fDimStatus, sts, t);
+            }
+
+            if (memcmp(old.fDac, h.fDac, sizeof(h.fDac)) || changed)
+            {
+                array<uint16_t, FAD::kNumDac*42> dacs;
+
+                for (int i=0; i<FAD::kNumDac; i++)
+                {
+                    const array<uint16_t, 42> dac = Compare(&fVecHeader[0], &fVecHeader[0].fDac[i]);
+                    memcpy(&dacs[i*42], &dac[0], sizeof(uint16_t)*42);
+                }
+
+                Update(fDimDac, dacs, t);
+            }
+
+            // -----------
+
+            static Time oldt(boost::date_time::neg_infin);
+            Time newt;
+
+            if (newt>oldt+boost::posix_time::seconds(1))
+            {
+                oldt = newt;
+
+                // --- RefClock
+
+                const array<uint32_t,42> clk = Compare(&fVecHeader[0], &fVecHeader[0].fFreqRefClock);
+                Update(fDimRefClock, clk, t);
+
+                // --- Temperatures
+
+                const array<int16_t,42> tmp[4] =
+                {
+                    Compare(&fVecHeader[0], &fVecHeader[0].fTempDrs[0]),    // 0-39:val, 40:min, 41:max
+                    Compare(&fVecHeader[0], &fVecHeader[0].fTempDrs[1]),    // 0-39:val, 40:min, 41:max
+                    Compare(&fVecHeader[0], &fVecHeader[0].fTempDrs[2]),    // 0-39:val, 40:min, 41:max
+                    Compare(&fVecHeader[0], &fVecHeader[0].fTempDrs[3])     // 0-39:val, 40:min, 41:max
+                };
+
+                vector<int16_t> data;
+                data.reserve(82);
+                data.push_back(tmp[0][40]);                                 // min: 0
+                data.insert(data.end(), tmp[0].data(), tmp[0].data()+40);   // val: 1-40
+                data.push_back(tmp[0][41]);                                 // max: 41
+                data.insert(data.end(), tmp[0].data(), tmp[0].data()+40);   // val: 42-81
+
+                for (int j=1; j<=3; j++)
+                {
+                    const array<int16_t,42> &ref = tmp[j];
+
+                    // Gloabl min
+                    if (ref[40]<data[0])           // 40=min
+                        data[0] = ref[40];
+
+                    // Global max
+                    if (ref[41]>data[41])          // 41=max
+                        data[41] = ref[41];
+
+                    for (int i=0; i<40; i++)
+                    {
+                        // min per board
+                        if (ref[i]<data[i+1])      // data:  1-40
+                            data[i+1] = ref[i];    // ref:   0-39
+
+                        // max per board
+                        if (ref[i]>data[i+42])     // data: 42-81
+                            data[i+42] = ref[i];   // ref:   0-39
+                    }
+                }
+
+                vector<float> deg(82);              //  0: global min,  1-40: min
+                for (int i=0; i<82; i++)            // 41: global max, 42-81: max
+                    deg[i] = data[i]/16.;
+
+                fDimTemperature.setData(deg.data(), 82*sizeof(float));
+                fDimTemperature.Update(t);
+            }
+
+        }
+    }
+
     void debugHead(int /*socket*/, const FAD::EventHeader &h)
     {
@@ -1377,120 +1561,6 @@
         fNumConnected = con;
 
-	const FAD::EventHeader old = fVecHeader[id];
-        fVecHeader[id] = h;
-
-        if (old.fVersion != h.fVersion || changed)
-        {
-            const array<uint16_t,42> ver = Compare(&fVecHeader[0], &fVecHeader[0].fVersion);
-
-            array<float,42> data;
-            for (int i=0; i<42; i++)
-            {
-                ostringstream str;
-                str << (ver[i]>>8) << '.' << (ver[i]&0xff);
-                data[i] = stof(str.str());
-            }
-            Update(fDimFwVersion, data);
-        }
-
-        if (old.fRunNumber != h.fRunNumber || changed)
-        {
-            const array<uint32_t,42> run = Compare(&fVecHeader[0], &fVecHeader[0].fRunNumber);
-            fDimRunNumber.Update(run);
-        }
-
-        if (old.fTriggerGeneratorPrescaler != h.fTriggerGeneratorPrescaler || changed)
-        {
-            const array<uint16_t,42> pre = Compare(&fVecHeader[0], &fVecHeader[0].fTriggerGeneratorPrescaler);
-            fDimPrescaler.Update(pre);
-        }
-
-        if (old.fDNA != h.fDNA || changed)
-        {
-            const array<uint64_t,42> dna = Compare(&fVecHeader[0], &fVecHeader[0].fDNA);
-            Update(fDimDNA, dna, 40);
-        }
-
-        if (old.fStatus != h.fStatus || changed)
-        {
-            const array<uint16_t,42> sts = CompareBits(&fVecHeader[0], &fVecHeader[0].fStatus);
-            Update(fDimStatus, sts);
-        }
-
-        if (memcmp(old.fDac, h.fDac, sizeof(h.fDac)) || changed)
-        {
-            array<uint16_t, FAD::kNumDac*42> dacs;
-
-            for (int i=0; i<FAD::kNumDac; i++)
-            {
-                const array<uint16_t, 42> dac = Compare(&fVecHeader[0], &fVecHeader[0].fDac[i]);
-                memcpy(&dacs[i*42], &dac[0], sizeof(uint16_t)*42);
-            }
-
-            Update(fDimDac, dacs);
-        }
-
-        // -----------
-
-        static Time oldt(boost::date_time::neg_infin);
-        Time newt;
-
-        if (newt>oldt+boost::posix_time::seconds(1))
-        {
-            oldt = newt;
-
-            // --- RefClock
-
-            const array<uint32_t,42> clk = Compare(&fVecHeader[0], &fVecHeader[0].fFreqRefClock);
-            Update(fDimRefClock, clk);
-
-            // --- Temperatures
-
-            const array<int16_t,42> tmp[4] =
-            {
-                Compare(&fVecHeader[0], &fVecHeader[0].fTempDrs[0]),    // 0-39:val, 40:min, 41:max
-                Compare(&fVecHeader[0], &fVecHeader[0].fTempDrs[1]),    // 0-39:val, 40:min, 41:max
-                Compare(&fVecHeader[0], &fVecHeader[0].fTempDrs[2]),    // 0-39:val, 40:min, 41:max
-                Compare(&fVecHeader[0], &fVecHeader[0].fTempDrs[3])     // 0-39:val, 40:min, 41:max
-            };
-
-            vector<int16_t> data;
-            data.reserve(82);
-            data.push_back(tmp[0][40]);                                 // min: 0
-            data.insert(data.end(), tmp[0].data(), tmp[0].data()+40);   // val: 1-40
-            data.push_back(tmp[0][41]);                                 // max: 41
-            data.insert(data.end(), tmp[0].data(), tmp[0].data()+40);   // val: 42-81
-
-            for (int j=1; j<=3; j++)
-            {
-                const array<int16_t,42> &ref = tmp[j];
-
-                // Gloabl min
-                if (ref[40]<data[0])           // 40=min
-                    data[0] = ref[40];
-
-                // Global max
-                if (ref[41]>data[41])          // 41=max
-                    data[41] = ref[41];
-
-                for (int i=0; i<40; i++)
-                {
-                    // min per board
-                    if (ref[i]<data[i+1])      // data:  1-40
-                        data[i+1] = ref[i];    // ref:   0-39
-
-                    // max per board
-                    if (ref[i]>data[i+42])     // data: 42-81
-                        data[i+42] = ref[i];   // ref:   0-39
-                }
-
-
-           }
-
-            vector<float> deg(82);              //  0: global min,  1-40: min
-            for (int i=0; i<82; i++)            // 41: global max, 42-81: max
-                deg[i] = data[i]/16.;
-            fDimTemperature.Update(deg);
-        }
+        const lock_guard<mutex> guard(fMutexDimQueue2);
+        fDimQueue2.push_back(make_tuple(Time(), changed, h));
     }
 };
