Prevent leaking of thread objects
authorunC0Rr
Tue, 27 Aug 2019 08:41:48 +0200
changeset 15365 fcdb6e3a9d36
parent 15364 114b036522a6
child 15366 381c828865e7
Prevent leaking of thread objects
hedgewars/SDLh.pas
hedgewars/uAI.pas
--- a/hedgewars/SDLh.pas	Tue Aug 27 06:05:03 2019 +0200
+++ b/hedgewars/SDLh.pas	Tue Aug 27 08:41:48 2019 +0200
@@ -478,7 +478,6 @@
     SDL_SCANCODE_KP_E = 192;
     SDL_SCANCODE_KP_F = 193;
     SDL_SCANCODE_KP_XOR = 194;
-    SDL_SCANCODE_KP_POWER = 195;
     SDL_SCANCODE_KP_PERCENT = 196;
     SDL_SCANCODE_KP_LESS = 197;
     SDL_SCANCODE_KP_GREATER = 198;
@@ -934,6 +933,7 @@
 
     PSDL_Thread = Pointer;
     PSDL_mutex = Pointer;
+    PSDL_sem = Pointer;
 
     TSDL_GLattr = (
         SDL_GL_RED_SIZE,
@@ -1161,6 +1161,7 @@
 function  SDL_CreateThread(fn: Pointer; name: PChar; data: Pointer): PSDL_Thread; cdecl; external SDLLibName;
 {$ENDIF}
 procedure SDL_WaitThread(thread: PSDL_Thread; status: PLongInt); cdecl; external SDLLibName;
+procedure SDL_DetachThread(thread: PSDL_Thread); cdecl; external SDLLibName;
 procedure SDL_KillThread(thread: PSDL_Thread); cdecl; external SDLLibName;
 
 function  SDL_CreateMutex: PSDL_mutex; cdecl; external SDLLibName;
@@ -1168,6 +1169,11 @@
 function  SDL_LockMutex(mutex: PSDL_mutex): LongInt; cdecl; external SDLLibName;
 function  SDL_UnlockMutex(mutex: PSDL_mutex): LongInt; cdecl; external SDLLibName;
 
+function  SDL_CreateSemaphore(initial_value: Longword): PSDL_sem; cdecl; external SDLLibName;
+procedure SDL_DestroySemaphore(sem: PSDL_sem); cdecl; external SDLLibName;
+function  SDL_SemWait(sem: PSDL_sem): LongInt; cdecl; external SDLLibName;
+function  SDL_SemPost(sem: PSDL_sem): LongInt; cdecl; external SDLLibName;
+
 function  SDL_GL_SetAttribute(attr: TSDL_GLattr; value: LongInt): LongInt; cdecl; external SDLLibName;
 procedure SDL_GL_SwapBuffers; cdecl; external SDLLibName;
 
--- a/hedgewars/uAI.pas	Tue Aug 27 06:05:03 2019 +0200
+++ b/hedgewars/uAI.pas	Tue Aug 27 08:41:48 2019 +0200
@@ -38,20 +38,15 @@
     CanUseAmmo: array [TAmmoType] of boolean;
     StopThinking: boolean;
     StartTicks: Longword;
-    ThinkThread: PSDL_Thread;
-    ThreadLock: PSDL_Mutex;
+    ThreadSem: PSDL_Sem;
 
 procedure FreeActionsList;
 begin
     AddFileLog('FreeActionsList called');
-    if (ThinkThread <> nil) then
-        begin
-        StopThinking:= true;
-        SDL_WaitThread(ThinkThread, nil);
-        end;
-    SDL_LockMutex(ThreadLock);
-    ThinkThread:= nil;
-    SDL_UnlockMutex(ThreadLock);
+
+    StopThinking:= true;
+    SDL_SemWait(ThreadSem);
+    SDL_SemPost(ThreadSem);
 
     if CurrentHedgehog <> nil then
         with CurrentHedgehog^ do
@@ -522,18 +517,18 @@
     end;
 
 Me^.State:= Me^.State and (not gstHHThinking);
-SDL_LockMutex(ThreadLock);
-ThinkThread:= nil;
-SDL_UnlockMutex(ThreadLock);
 Think:= 0;
+SDL_SemPost(ThreadSem);
 end;
 
 procedure StartThink(Me: PGear);
+var ThinkThread: PSDL_Thread;
 begin
 if ((Me^.State and (gstAttacking or gstHHJumping or gstMoving)) <> 0)
 or isInMultiShoot then
     exit;
 
+SDL_SemWait(ThreadSem);
 //DeleteCI(Me); // this will break demo/netplay
 
 Me^.State:= Me^.State or gstHHThinking;
@@ -556,9 +551,8 @@
 
 FillBonuses(((Me^.State and gstAttacked) <> 0) and (not isInMultiShoot) and ((GameFlags and gfInfAttack) = 0));
 
-SDL_LockMutex(ThreadLock);
 ThinkThread:= SDL_CreateThread(@Think, PChar('think'), Me);
-SDL_UnlockMutex(ThreadLock);
+SDL_DetachThread(ThinkThread);
 end;
 
 {$IFDEF DEBUGAI}
@@ -610,14 +604,13 @@
 procedure initModule;
 begin
     StartTicks:= 0;
-    ThinkThread:= nil;
-    ThreadLock:= SDL_CreateMutex();
+    ThreadSem:= SDL_CreateSemaphore(1);
 end;
 
 procedure freeModule;
 begin
     FreeActionsList();
-    SDL_DestroyMutex(ThreadLock);
+    SDL_DestroySemaphore(ThreadSem);
 end;
 
 end.