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

Dominique Leducq dleducq at magellan-ing.fr
Thu Nov 30 12:29:16 CET 2006


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 ? 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 ?


> 
> > > > And symetrically, a function to be called after any other library call in the thread, 
> > > > which flushes the input/output streams and calls CurrentTM.ReleaseThreadVars.
> > > 
> > > 
> > > Correct. The CurrentTM.Releasevars and flushing should be done just before your
> > > thread ends. This should be done always, with any version of FPC.
> > > 
> > > Michael.
> > 
> > Thanks Michael for your (very) fast answer !
> 
> De rien..
> 
> Michael.




More information about the fpc-devel mailing list