From 16010570bbbc8d3f7560415ef0d994e6b716b5e7 Mon Sep 17 00:00:00 2001 From: ondrej Date: Wed, 4 Nov 2020 14:55:40 +0000 Subject: [PATCH] * lazy thread initialization support git-svn-id: trunk@47308 - (cherry picked from commit c64429cdd0465c60e775c77c41afa464ab0a527f) --- rtl/beos/bethreads.pp | 2 ++ rtl/inc/thread.inc | 28 ++++++++++++++++++++++++++++ rtl/inc/threadh.inc | 4 ++++ rtl/netware/systhrd.inc | 2 ++ rtl/netwlibc/systhrd.inc | 2 ++ rtl/unix/cthreads.pp | 7 ++++++- rtl/win/systhrd.inc | 7 ++++++- 7 files changed, 50 insertions(+), 2 deletions(-) diff --git a/rtl/beos/bethreads.pp b/rtl/beos/bethreads.pp index fe437f0474..ee2c47c6e5 100644 --- a/rtl/beos/bethreads.pp +++ b/rtl/beos/bethreads.pp @@ -168,6 +168,8 @@ Uses pthread_key_create(@TLSKey,nil); InitThreadVars(@CRelocateThreadvar); {$endif HASTHREADVAR} + { lazy initialize thread support } + LazyInitThreading; IsMultiThread:=true; end; { the only way to pass data to the newly created thread diff --git a/rtl/inc/thread.inc b/rtl/inc/thread.inc index 94f8a602ef..8dec424044 100644 --- a/rtl/inc/thread.inc +++ b/rtl/inc/thread.inc @@ -342,6 +342,34 @@ begin currenttm.RTLEventWaitForTimeout(state,timeout); end; +{ --------------------------------------------------------------------- + lazy thread initialization support + ---------------------------------------------------------------------} + +var + LazyInitThreadingProcs : array of TProcedure = nil; +procedure RegisterLazyInitThreadingProc(const proc: TProcedure); +begin + if IsMultiThread then + begin + { multithreading is already enabled - execute directly } + proc(); + end + else + begin + SetLength(LazyInitThreadingProcs,Length(LazyInitThreadingProcs)+1); + LazyInitThreadingProcs[high(LazyInitThreadingProcs)]:=proc; + end; +end; + +procedure LazyInitThreading; +var + i: Integer; +begin + for i:=0 to high(LazyInitThreadingProcs) do + LazyInitThreadingProcs[i](); +end; + { --------------------------------------------------------------------- ThreadManager which gives run-time error. Use if no thread support. ---------------------------------------------------------------------} diff --git a/rtl/inc/threadh.inc b/rtl/inc/threadh.inc index 0d0b626f28..4f23d029e8 100644 --- a/rtl/inc/threadh.inc +++ b/rtl/inc/threadh.inc @@ -182,3 +182,7 @@ procedure RTLEventResetEvent(state:pRTLEvent); procedure RTLEventWaitFor(state:pRTLEvent); procedure RTLEventWaitFor(state:pRTLEvent;timeout : longint); +{ lazy thread initialization support } +procedure RegisterLazyInitThreadingProc(const proc: TProcedure); +{ do not call LazyInitThreading directly} +procedure LazyInitThreading; diff --git a/rtl/netware/systhrd.inc b/rtl/netware/systhrd.inc index c362c59704..298fc0a9ff 100644 --- a/rtl/netware/systhrd.inc +++ b/rtl/netware/systhrd.inc @@ -156,6 +156,8 @@ function SysBeginThread(sa : Pointer;stacksize : SizeUInt; if not IsMultiThread then begin InitThreadVars(@SysRelocateThreadvar); + { lazy initialize thread support } + LazyInitThreading; IsMultithread:=true; end; { the only way to pass data to the newly created thread } diff --git a/rtl/netwlibc/systhrd.inc b/rtl/netwlibc/systhrd.inc index 5d12022fad..6a3b5232b0 100644 --- a/rtl/netwlibc/systhrd.inc +++ b/rtl/netwlibc/systhrd.inc @@ -133,6 +133,8 @@ { We're still running in single thread mode, setup the TLS } pthread_key_create(@TLSKey,nil); InitThreadVars(@SysRelocateThreadvar); + { lazy initialize thread support } + LazyInitThreading; IsMultiThread:=true; end; { the only way to pass data to the newly created thread diff --git a/rtl/unix/cthreads.pp b/rtl/unix/cthreads.pp index 76bd636f52..2ee2d5a484 100644 --- a/rtl/unix/cthreads.pp +++ b/rtl/unix/cthreads.pp @@ -351,7 +351,12 @@ Type PINTRTLEvent = ^TINTRTLEvent; { Initialize multithreading if not done } if not TLSInitialized then InitCTLS; - IsMultiThread:=true; + if not IsMultiThread then + begin + { We're still running in single thread mode, lazy initialize thread support } + LazyInitThreading; + IsMultiThread:=true; + end; { the only way to pass data to the newly created thread in a MT safe way, is to use the heap } diff --git a/rtl/win/systhrd.inc b/rtl/win/systhrd.inc index 10bb07fda4..1d366ece51 100644 --- a/rtl/win/systhrd.inc +++ b/rtl/win/systhrd.inc @@ -256,7 +256,12 @@ var {$endif DEBUG_MT} { Initialize multithreading if not done } SysInitTLS; - IsMultiThread:=true; + if not IsMultiThread then + begin + { lazy initialize thread support } + LazyInitThreading; + IsMultiThread:=true; + end; { the only way to pass data to the newly created thread in a MT safe way, is to use the heap }