[fpc-devel] calls to Fpc-made library from C not thread-safe

Michael Van Canneyt michael.vancanneyt at wisa.be
Thu Nov 30 14:11:55 CET 2006



On Thu, 30 Nov 2006, Dominique Leducq wrote:

> Ooops. Did a 'reply to list', but that didn't work. Try again...
> 
> On Thu, 30 Nov 2006 10:48:58 +0100 (CET)
> Michael Van Canneyt <michael.vancanneyt at wisa.be> wrote:
> 
> > 
> > 
> > On Thu, 30 Nov 2006, Dominique Leducq wrote:
> > 
> > > On Thu, 30 Nov 2006 10:11:17 +0100 (CET)
> > > Michael Van Canneyt <michael.vancanneyt at wisa.be> wrote:
> > > 
> > > > 
> > > > 
> > > > On Thu, 30 Nov 2006, Dominique Leducq wrote:
> > > > 
> > > > > Hi,
> > > > > 
> > > > > I have a library compiled with Fpc, used from C/C++ programs.
> > > > > When these C programs call functions of the library from different threads, things break.
> > > > 
> > > > This is unfortunately true :-)
> > > > 
> > > > > 
> > > > > As I understand it, the exception stack(s), the standard input/output streams, the threadID 
> > > > > and stack checking variables use thread variables, and when the thread is created from C, 
> > > > > this variables are not allocated nor initialized.
> > > > 
> > > > This is correct.
> > > > 
> > > > > As a workaround, I thought I could export a function from the library, to be called in each 
> > > > > thread before any other library call, which would call CurrentTM.AllocateThreadVars and 
> > > > > System.InitThread.
> > > > 
> > > > This should no longer be needed. I implemented some fixes recently which
> > > > fixes this. If you're working with an officially released version, then you
> > > > have the right solution. Calling CurrentTM.AllocateThreadVars should be
> > > > enough.
> > > 
> > > I use Fpc 2.1.1 (currently rev 5448), and something still seems to be needed. In which revision have your fixes been applied ?
> > 
> > Revision 5474 for linux, 5475 for Windows.
> 
> OK.
> 
> But: System.IniThread performs some initialization on system thread variables. Isn't this still needed ? 

Yes it is still needed. 
The code I tested always created 1 thread in pascal, so that wasn't an issue.

So you should call this too.


> OK, SysInitExceptions for now only sets two stack pointers to nil,
> and AllocateThreadVars already set the variables to zero (at least for Unices). But what about the standard IO streams (SysInitStdIO)? Does a WriteLn('string'), for example, work without that ? What about ThreadID ?
> Besides, what about this code from rtl/unix/cthreads.pp (CBeginThread):
> 
> 
> 
>       { Initialize multithreading if not done }
>       if not IsMultiThread then
>         begin
>           if (InterLockedExchange(longint(IsMultiThread),1) = 0) then
>             begin
>               { We're still running in single thread mode, setup the TLS }
>                pthread_key_create(@TLSKey,nil);
>               InitThreadVars(@CRelocateThreadvar);
>             end
>         end;
> ?
> 
> If I haven't created a thread from within my FPC library before, this code has never been run, and thus IsMultiThread is still 0, TLSKey is not created, and thread variables not initialized. Right ?

You are right.

Michael.



More information about the fpc-devel mailing list