Some work on new IPC, built with the use of mutexes and condition variables qmlfrontend
authorunc0rr
Thu, 18 Sep 2014 00:19:05 +0400
branchqmlfrontend
changeset 10410 669bfa55cd70
parent 10408 5fdc42ef5bcc
child 10412 9a8d4efcf3fa
Some work on new IPC, built with the use of mutexes and condition variables
hedgewars/SDLh.pas
hedgewars/uFLIPC.pas
hedgewars/uIO.pas
--- a/hedgewars/SDLh.pas	Tue Sep 16 12:46:58 2014 +0400
+++ b/hedgewars/SDLh.pas	Thu Sep 18 00:19:05 2014 +0400
@@ -843,6 +843,7 @@
     PSDL_Thread = Pointer;
     PSDL_mutex = Pointer;
     PSDL_sem = Pointer;
+    PSDL_cond = Pointer;
 
     TSDL_GLattr = (
         SDL_GL_RED_SIZE,
@@ -1065,6 +1066,13 @@
 function  SDL_LockMutex(mutex: PSDL_mutex): LongInt; cdecl; external SDLLibName {$IFNDEF SDL2}name 'SDL_mutexP'{$ENDIF};
 function  SDL_UnlockMutex(mutex: PSDL_mutex): LongInt; cdecl; external SDLLibName {$IFNDEF SDL2}name 'SDL_mutexV'{$ENDIF};
 
+function  SDL_CreateCond: PSDL_cond; cdecl; external SDLLibName;
+procedure SDL_DestroyCond(cond: PSDL_cond); cdecl; external SDLLibName;
+function  SDL_CondSignal(cond: PSDL_cond): LongInt; cdecl; external SDLLibName;
+function  SDL_CondBroadcast(cond: PSDL_cond): LongInt; cdecl; external SDLLibName;
+function  SDL_CondWait(cond: PSDL_cond; mut: PSDL_mutex): LongInt; cdecl; external SDLLibName;
+function  SDL_CondWaitTimeout(cond: PSDL_cond; mut: PSDL_mutex; ms: Longword): LongInt; cdecl; external SDLLibName;
+
 
 function SDL_CreateSemaphore(initial_value: Longword): PSDL_sem; cdecl; external SDLLibName;
 procedure SDL_DestroySemaphore(sem: PSDL_sem); cdecl; external SDLLibName;
--- a/hedgewars/uFLIPC.pas	Tue Sep 16 12:46:58 2014 +0400
+++ b/hedgewars/uFLIPC.pas	Thu Sep 18 00:19:05 2014 +0400
@@ -1,7 +1,81 @@
 unit uFLIPC;
+interface
+uses SDLh;
+
+type TIPCMessage = record
+                   str: shortstring;
+                   len: Longword;
+                   buf: Pointer
+               end;
 
-interface
+var msgFrontend, msgEngine: TIPCMessage;
+    mutFrontend, mutEngine: PSDL_mutex;
+    condFrontend, condEngine: PSDL_cond;
+
+procedure initIPC;
+procedure freeIPC;
+
+procedure ipcToEngine(s: shortstring);
+function  ipcReadFromEngine: shortstring;
+function  ipcCheckFromEngine: boolean;
 
 implementation
 
+procedure ipcToEngine(s: shortstring);
+begin
+    SDL_LockMutex(mutEngine);
+    while (msgEngine.str[0] > #0) or (msgEngine.buf <> nil) do
+        SDL_CondWait(condEngine, mutEngine);
+
+    msgEngine.str:= s;
+    SDL_CondSignal(condEngine);
+    SDL_UnlockMutex(mutEngine)
+end;
+
+function ipcReadFromEngine: shortstring;
+begin
+    SDL_LockMutex(mutFrontend);
+    while (msgFrontend.str[0] = #0) and (msgFrontend.buf = nil) do
+        SDL_CondWait(condFrontend, mutFrontend);
+
+    ipcReadFromEngine:= msgFrontend.str;
+    msgFrontend.str[0]:= #0;
+    if msgFrontend.buf <> nil then
+    begin
+        FreeMem(msgFrontend.buf, msgFrontend.len);
+        msgFrontend.buf:= nil
+    end;
+
+    SDL_CondSignal(condFrontend);
+    SDL_UnlockMutex(mutFrontend)
+end;
+
+function ipcCheckFromEngine: boolean;
+begin
+    SDL_LockMutex(mutFrontend);
+    ipcCheckFromEngine:= (msgFrontend.str[0] > #0) or (msgFrontend.buf <> nil);
+    SDL_UnlockMutex(mutFrontend)
+end;
+
+procedure initIPC;
+begin
+    msgFrontend.str:= '';
+    msgFrontend.buf:= nil;
+    msgEngine.str:= '';
+    msgEngine.buf:= nil;
+
+    mutFrontend:= SDL_CreateMutex;
+    mutEngine:= SDL_CreateMutex;
+    condFrontend:= SDL_CreateCond;
+    condEngine:= SDL_CreateCond;
+end;
+
+procedure freeIPC;
+begin
+    SDL_DestroyMutex(mutFrontend);
+    SDL_DestroyMutex(mutEngine);
+    SDL_DestroyCond(condFrontend);
+    SDL_DestroyCond(condEngine);
+end;
+
 end.
--- a/hedgewars/uIO.pas	Tue Sep 16 12:46:58 2014 +0400
+++ b/hedgewars/uIO.pas	Thu Sep 18 00:19:05 2014 +0400
@@ -39,7 +39,7 @@
 procedure doPut(putX, putY: LongInt; fromAI: boolean);
 
 implementation
-uses uConsole, uConsts, uVariables, uCommands, uUtils, uDebug;
+uses uConsole, uConsts, uVariables, uCommands, uUtils, uDebug, uFLIPC;
 
 const
     cSendEmptyPacketTime = 1000;