瀏覽代碼

+ WebAssembly threads: spinwait until ThreadHasFinished becomes true in
WasiWaitForThreadTerminate, before freeing the thread TLS and stack block, to
avoid race condition with a thread that is finishing (i.e. the main threadproc
is done), but still executing internal Pascal code inside
FPCWasmThreadStartPascal.

Nikolay Nikolov 1 年之前
父節點
當前提交
a0ac317aae
共有 1 個文件被更改,包括 3 次插入0 次删除
  1. 3 0
      rtl/wasi/systhrd.inc

+ 3 - 0
rtl/wasi/systhrd.inc

@@ -587,6 +587,9 @@ begin
   UnLockMuTex(PWasmThread(ThreadHandle)^.Running);
   UnLockMuTex(PWasmThread(ThreadHandle)^.Running);
   {$IFDEF DEBUGWASMTHREADS}DebugWriteln('WaitForThreadTerminate('+IntToStr(PtrUINT(TH))+') : Lock released');{$ENDIF}
   {$IFDEF DEBUGWASMTHREADS}DebugWriteln('WaitForThreadTerminate('+IntToStr(PtrUINT(TH))+') : Lock released');{$ENDIF}
   WasiWaitForThreadTerminate:=DWord(Res);
   WasiWaitForThreadTerminate:=DWord(Res);
+  {$IFDEF DEBUGWASMTHREADS}DebugWriteln('WaitForThreadTerminate('+IntToStr(PtrUINT(TH))+') : Waiting until ThreadHasFinished becomes true');{$ENDIF}
+  repeat
+  until fpc_wasm32_i32_atomic_load8_u(@P^.ThreadHasFinished)<>0;
   {$IFDEF DEBUGWASMTHREADS}DebugWriteln('WaitForThreadTerminate('+IntToStr(PtrUINT(TH))+') : FreeStackAndTlsBlock');{$ENDIF}
   {$IFDEF DEBUGWASMTHREADS}DebugWriteln('WaitForThreadTerminate('+IntToStr(PtrUINT(TH))+') : FreeStackAndTlsBlock');{$ENDIF}
   FreeStackAndTlsBlock(TH);
   FreeStackAndTlsBlock(TH);
 end;
 end;