[Lazarus] Mutlithreaded Dll Callback crashes my Application

Alexander Grau alex at grauonline.de
Wed Aug 25 16:58:42 CEST 2010


Maik,

As you did, I did write a new test program - this one uses 30 threads - 
it works fine (no crash) until the moment I enable the a simple 
'writeln' inside a callack. You can see that it works by the increased 
counters for each thread that are displayed after the program 
successfully finished.

So:  external multiple threads calling fine until you use FPC runtime 
code :/ ...


Regards,
Alexander


program project1;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes,
  sysutils
  { you can add units after this };

{$R project1.res}

type
  MT_THREAD_HANDLE   = Pointer;

  tdummy = class
    idx: integer;
    constructor create();
    procedure test;
  end;


function vcmtdll_NewThread: MT_THREAD_HANDLE; cdecl; external 'vcmtdll.dll';
procedure vcmtdll_DeleteThread(ahandle : MT_THREAD_HANDLE); cdecl; 
external 'vcmtdll.dll';
procedure vcmtdll_RegisterCallback(ahandle : MT_THREAD_HANDLE; pCBFunc : 
Pointer; pCBData : Pointer); cdecl; external 'vcmtdll.dll';
procedure vcmtdll_StartThread(ahandle : MT_THREAD_HANDLE; iDelay : 
Cardinal); cdecl; external 'vcmtdll.dll';

const
  COUNT = 30;

var
  handles: array[1..COUNT] of MT_THREAD_HANDLE;
  objects: array[1..COUNT] of tdummy;


constructor tdummy.create();
begin
  inherited create;
  idx:=0;
end;

procedure tdummy.test;
begin
  inc(idx);
end;

procedure OnExecuteClb(pCBData : Pointer); cdecl;
var
  i: integer;
begin
  //  writeln('onExecuteClb');  <-- this line will crash
  for i:=1 to 30 do
    tdummy(pCBData).test();
end;

var
  i: integer;

begin
  writeln('start');
  for i:=1 to COUNT do objects[i]:=TDummy.create;

  for i:=1 to COUNT do
    Handles[i]  := vcmtdll_NewThread();

  for i:=1 to COUNT do
    vcmtdll_RegisterCallback(handles[i], @OnExecuteClb, objects[i]);

  for i:=1 to COUNT do
    vcmtdll_StartThread(handles[i], 1000);

  writeln('go');
  sleep(2000);

  writeln('freeing');
  for i:=1 to COUNT do
    vcmtdll_DeleteThread(handles[i]);

  for i:=1 to COUNT do writeln(objects[i].idx);

  writeln('bye');
end.




Maik Wojcieszak schrieb:
> Alexander,
>
> I tried you're test app already and it worked as you said. So does my 
> test app if I do only one thing at time. After changing you're test 
> app to process
> multiple threads at the same time it crashed too.
>
> Alexander Grau schrieb:
>>
>>
>> Maik,
>>
>> Did you try out the console test program I posted? It uses your DLL 
>> that runs a C thread and that C thread calls back the FPC function. 
>> Even more, this FPC callback function then calls a FPC object method.
>>
>> My program shows that there is nothing wrong with FPC (on Win32) and 
>> external C threads - it just works.
> Well, it doesn't if you stress this stuff a bit.
>>
>> My assumption :  there is something else wrong in your code - use my 
>> code and add one piece after the other of your code. For example, 
>> first just try to make my test app a simple LCL app (just a simple 
>> form). If that works too, add the dynamic function mapping you used. 
>> If that works too, make the wrapper (TComponent) you wrote etc.
> The question is: What is wrong ?
>>
>> Again : You can call FPC functions/objects in external C threads - 
>> there must be something else wrong in your program ;-) ...
> ...
>
> I've choosen the vortex (beep )binding as an example because my dll 
> does exactly the same.
> In fact it uses the vortex library to implement user protocols. There 
> must be a reason for those guys (and the
> vortex programmers) to add a mechanism to use a different threading 
> when using FPC.
> At the moment I will follow this idea to check if it solves my problem 
> and post my result here.
>
> Maik
>
>
> -- 
> _______________________________________________
> Lazarus mailing list
> Lazarus at lists.lazarus.freepascal.org
> http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
>





More information about the Lazarus mailing list