--- 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;