[Lazarus] Mutlithreaded Dll Callback crashes my Application
Sven Barth
pascaldragon at googlemail.com
Thu Aug 26 22:06:26 CEST 2010
On 26.08.2010 20:52, Alexander Grau wrote:
>
> I'm currently trying to summarize all aspects we discussed to add them
> to the FreePascal Multithreading wiki page (see below) - did I forget
> something that should be mentioned?
>
> Thanks,
> Alexander
>
>
>
> External threads
>
>
> To make Free Pascal's threading system to work properly, each newly
> created FPC thread needs to be initialized (more exactly, the thread
> local storage per thread needs to be initialized so threadvars and heap
> are working). That is fully automatically done for you if you use
> BeginThread (or indirectly by using the TThread class). However, if you
> use threads that were created without BeginThread (i.e. external
> threads), additional work (currently) might be required. External
> threads also include those that were created in external C libraries
> (.DLL/.so).
It's not only initializing the thread local storage (which is Windows
only by the way, the threadvar system on e.g. Linux might have a
different name), but also the exception and the I/O system
>
> Things to consider when using external threads (might not be needed in
> all or future compiler versions):
>
>
> A) Initialize the FPC's threading system by creating a dummy thread:
>
> { initialise threading system }
> with tc.create(false) do
> begin
> waitfor;
> free;
> end;
You should not forget to write how a class of type "tc" looks like :)
> B) Make the runtime aware that your application uses multiple threads in
> the first line of your application (.dpr):
> IsMultithread:=true;
>
This is not needed. That is set to true automatically if a thread is
created inside FPC.
> (This will make FPC routines to perform locks here and there.)
> C) Do not use external threads at all - use FPC threads.
>
Should be put at the top of the list ^^
> D) If for some reason this doesn't work for you, try this code in your
> external thread function:
>
> function ExternalThread(param: Pointer): LongInt; stdcall;
> var
> tm: TThreadManager;
> begin
> GetThreadManager(tm);
> tm.AllocateThreadVars;
> InitThread(100000000);
> someFunc(param);
> Result:=0;
> end;
>
The number in InitThread is the initial stack length and as I was a bit
lazy I simply set it to a huge number. So don't nail me on that one :D
You might also replace the "someFunc(param)" with "{ do something
threaded }" or something like that.
>
> How to identify if your code is executed in an external thread context
>
> 1. Ask the OS for the ID of the current thread at your application's start
>
> Win32: WriteLn('Thread ID=', GetCurrentThreadID);
> Darwin: WriteLn('Thread ID=', GetThreadID); Linux: Writeln('Thread ID=',
> TThreadID(pthread_self) );
>
> 2. Ask again for the ID of the current thread inside the thread function
> and compare this by the result of step 1.
I don't know whether this works (reliably) when the threadvars haven't
been allocated yet. I don't even know what happens if you access
unallocated threadvars O.o
Regards,
Sven
More information about the Lazarus
mailing list