Introduce barriers between messages to different engine instances qmlfrontend
authorunc0rr
Sat, 12 Dec 2015 23:38:18 +0300
branchqmlfrontend
changeset 11457 78860824b5a5
parent 11456 6e9b12864856
child 11458 e7c7ca0c1556
Introduce barriers between messages to different engine instances
hedgewars/uFLIPC.pas
hedgewars/uFLRunQueue.pas
hedgewars/uFLTypes.pas
--- a/hedgewars/uFLIPC.pas	Thu Dec 10 23:49:12 2015 +0300
+++ b/hedgewars/uFLIPC.pas	Sat Dec 12 23:38:18 2015 +0300
@@ -7,7 +7,8 @@
 
 procedure ipcToEngine(s: shortstring);
 procedure ipcToEngineRaw(p: pointer; len: Longword);
-procedure ipcCleanEngineQueue();
+procedure ipcSetEngineBarrier();
+procedure ipcRemoveBarrierFromEngineQueue();
 //function  ipcReadFromEngine: shortstring;
 //function  ipcCheckFromEngine: boolean;
 
@@ -38,6 +39,7 @@
     SDL_LockMutex(queue^.mut);
 
     s.next:= nil;
+    s.barrier:= 0;
 
     if (queue^.msg.next = nil) and (queue^.msg.str[0] = #0) and (queue^.msg.buf = nil) then
     begin
@@ -57,7 +59,8 @@
 var pmsg: PIPCMessage;
 begin
     SDL_LockMutex(queue^.mut);
-    while (queue^.msg.str[0] = #0) and (queue^.msg.buf = nil) and (queue^.msg.next = nil) do
+    while ((queue^.msg.str[0] = #0) and (queue^.msg.buf = nil))
+            and ((queue^.msg.barrier > 0) or (queue^.msg.next = nil) or ((queue^.msg.next^.barrier > 0) and (queue^.msg.next^.str[0] = #0) and (queue^.msg.next^.buf = nil))) do
         SDL_CondWait(queue^.cond, queue^.mut);
 
     if (queue^.msg.str[0] <> #0) or (queue^.msg.buf <> nil) then
@@ -69,9 +72,16 @@
         begin
             pmsg:= queue^.msg.next;
             ipcRead:= pmsg^;
-            queue^.msg.next:= pmsg^.next;
-            if queue^.msg.next = nil then queue^.last:= @queue^.msg;
-            dispose(pmsg)
+            if pmsg^.barrier > 0 then
+            begin
+                pmsg^.str[0]:= #0;
+                pmsg^.buf:= nil
+            end else
+            begin
+                queue^.msg.next:= pmsg^.next;
+                if queue^.msg.next = nil then queue^.last:= @queue^.msg;
+                dispose(pmsg)
+            end
         end;
 
     SDL_UnlockMutex(queue^.mut)
@@ -80,7 +90,8 @@
 function ipcCheck(queue: PIPCQueue): boolean;
 begin
     SDL_LockMutex(queue^.mut);
-    ipcCheck:= (queue^.msg.str[0] > #0) or (queue^.msg.buf <> nil) or (queue^.msg.next <> nil);
+    ipcCheck:= (queue^.msg.str[0] > #0) or (queue^.msg.buf <> nil) or
+               ((queue^.msg.barrier = 0) and (queue^.msg.next <> nil) and ((queue^.msg.next^.barrier = 0) or (queue^.msg.next^.str[0] <> #0) or (queue^.msg.next^.buf <> nil)));
     SDL_UnlockMutex(queue^.mut)
 end;
 
@@ -100,7 +111,16 @@
     ipcSend(msg, queueFrontend)
 end;
 
-procedure ipcCleanEngineQueue();
+procedure ipcSetEngineBarrier();
+begin
+    SDL_LockMutex(queueEngine^.mut);
+
+    inc(queueEngine^.last^.barrier);
+
+    SDL_UnlockMutex(queueEngine^.mut);
+end;
+
+procedure ipcRemoveBarrierFromEngineQueue();
 var pmsg, t: PIPCMessage;
     q: PIPCQueue;
 begin
@@ -109,21 +129,40 @@
     SDL_LockMutex(q^.mut);
 
     pmsg:= @q^.msg;
-    q^.last:= pmsg;
+    q^.last:= @q^.msg;
 
     while pmsg <> nil do
     begin
         t:= pmsg^.next;
+        q^.msg.next:= t;
 
         if pmsg^.buf <> nil then
             FreeMem(pmsg^.buf, pmsg^.len);
 
         if pmsg <> @q^.msg then
-            dispose(pmsg);
+            if pmsg^.barrier = 0 then
+                dispose(pmsg)
+            else
+            if pmsg^.barrier = 1 then
+            begin
+                dispose(pmsg);
+                t:= nil
+            end else
+            begin
+                dec(pmsg^.barrier);
+                q^.msg.next:= pmsg;
+                t:= nil
+            end
+        else
+            if pmsg^.barrier > 0 then 
+            begin
+                dec(pmsg^.barrier);
+                t:= nil
+            end;
+
         pmsg:= t
     end;
 
-    q^.msg.next:= nil;
     q^.msg.str[0]:= #0;
     q^.msg.buf:= nil;
 
--- a/hedgewars/uFLRunQueue.pas	Thu Dec 10 23:49:12 2015 +0300
+++ b/hedgewars/uFLRunQueue.pas	Sat Dec 12 23:38:18 2015 +0300
@@ -17,7 +17,7 @@
         if runQueue^.gameType = gtPreview then
             sendUI(mtRenderingPreview, nil, 0);
 
-        ipcCleanEngineQueue();
+        ipcRemoveBarrierFromEngineQueue();
         RunEngine(runQueue^.argumentsNumber, @runQueue^.argv);
 
         sendConfig(runQueue)
@@ -36,6 +36,8 @@
 var pConfig, t, tt: PGameConfig;
     i: Longword;
 begin
+    ipcSetEngineBarrier();
+
     new(pConfig);
     pConfig^:= config;
 
--- a/hedgewars/uFLTypes.pas	Thu Dec 10 23:49:12 2015 +0300
+++ b/hedgewars/uFLTypes.pas	Sat Dec 12 23:38:18 2015 +0300
@@ -24,6 +24,7 @@
                    str: shortstring;
                    len: Longword;
                    buf: Pointer;
+                   barrier: Longword;
                    next: PIPCMessage;
                end;
     PIPCQueue = ^TIPCQueue;