[fpc-pascal] Function reference doesn't capture in thread

Hairy Pixels genericptr at gmail.com
Sat Sep 17 07:02:26 CEST 2022


Can anyone explain why this program doesn’t capture the state of the local variable “I” and execute in order? It will return something like this:

Invoked: 3 id: 00000001029D41C0
Invoked: 0 id: 00000001029D42C0
Invoked: 0 id: 00000001029D44C0
Invoked: 0 id: 00000001029D43C0

It works if you call Start directly before WaitFor, but why? I would expect the function reference to capture i, start the thread and then block the program after the sleep calls but instead the sleep calls appear to do nothing and the program exists immediately.

=================================

{$mode objfpc}
{$modeswitch anonymousfunctions}
{$modeswitch functionreferences}
{$modeswitch arrayoperators}

program test;
uses
  Cthreads, SysUtils, Classes;

type
  TProc = reference to procedure;
  TCallback = class(TThread)
    private
      proc: TProc;
    public
      constructor Create(p: TProc);
      procedure Execute; override;
end;

procedure TCallback.Execute;
begin
  proc();
  Sleep(100);
end;

constructor TCallback.Create(p: TProc);
begin
  inherited Create(true);

  proc := p;
end;

var
  i: integer;
  callback: TCallback;
  callbacks: array of TCallback = ();
begin
  for i := 1 to 4 do
    begin
      callback := TCallback.Create(procedure
                  begin
                    writeln('Invoked: ', i, ' id: ', HexStr(TThread.CurrentThread));
                  end);

      callback.Start;
      callbacks += [callback];
    end;

  for i := 0 to High(callbacks) do
    callbacks[i].WaitFor;
end.

Regards,
	Ryan Joseph



More information about the fpc-pascal mailing list