[fpc-pascal] Call function in shared library from multiple threads

Michael Van Canneyt michael at freepascal.org
Thu Mar 30 14:49:10 CEST 2017



On Thu, 30 Mar 2017, Krzysztof wrote:

> Hi,
>
> I'm wondering if shared libraries (on Linux) support call exported function
> from multiple threads. I made small demo. Threads send JSON PChar into
> shared lib function which parse it and log in syslog. No global vars,
> everything locally in function. But even that I'm getting random errors
> like:

It should be supported but must have threads support compiled-in.

You didn't add cthreads to the uses list of the library, so your 
library will not function when called from multiple threads.

Of course, you need to keep your code thread-safe.
And indeed, not all RTL calls are thread safe. 
If any initialization must happen, it must happen the first time the library
is loaded (or it must be done in critical sections).

Michael.
>
> 29.03.2017 16:33    kernel    [26260.212884] traps: test_libmjrende[12177]
> general protection ip:7fe823eed2f1 sp:7fe8238571e0 error:0 in
> libmjrender.so[7fe823de0000+284000]
> 29.03.2017 16:36    kernel    [26443.509924] test_libmjrende[12247]:
> segfault at 7f5e02d179f0 ip 00007f5e02d1797c sp 00007f5e02d179f0 error 7 in
> libmjrender.so[7f5e02c02000+286000]
> 29.03.2017 16:42    kernel    [26819.543353] test_libmjrende[12350]:
> segfault at 7f1f1d65b0a0 ip 00007f1f1d65b0a0 sp 00007f1f0c000fd8 error 15
> in libmjrender.so[7f1f1d62e000+112000]
> 29.03.2017 16:39    kernel    [26627.190568] test_libmjrende[12297]:
> segfault at 8 ip 00007fe4c6851c2c sp 00007fe4c0766c90 error 4 in
> libc-2.23.so[7fe4c67d0000+1bf000]
>
> I guess that just not all RTL are thread safe and this is not supported.
> Even critical sections don't work here.
> This is function:
>
> procedure Test(ACounter: Integer; AJson: PChar); cdecl;
> var
>  js: TJSONObject=nil;
>  jp: TJSONParser=nil;
>  i: Integer;
>  s: String;
> begin
>  syslog(log_info, 'Enter: %d', [ACounter]);
>  try try
>    jp := TJSONParser.Create(AJson);
>    js := TJSONObject(jp.Parse);
>    FreeAndNil(jp);
>    Sleep(500);
>    i := js.Get('1', -1);
>    Sleep(500);
>    s := js.Get('2', '');
>    syslog(log_info, 'Got %d: %d %s', [ACounter, i, pchar(s)]);
>  except on e: Exception do
>    begin
>      syslog(log_info, 'Error: %s', [PChar(e.Message)]);
>      raise;
>    end;
>  end;
>  finally
>    FreeAndNil(jp);
>    FreeAndNil(js);
>    syslog(log_info, 'Leave: %d', [ACounter]);
>  end;
> end;
>
> Attached also full source with library and client.
>
> Regards
>



More information about the fpc-pascal mailing list