Documentation for TThread.RemoveQueuedEvents
Original Reporter info from Mantis: Martin @martin_frb
-
Reporter name: Martin Friebe
Original Reporter info from Mantis: Martin @martin_frb
- Reporter name: Martin Friebe
Description:
https://www.freepascal.org/docs-html/rtl/classes/tthread.removequeuedevents.html
all calls to the given method .... are removed.
type TThreadMethod = procedure of object;
public class procedure TThread.RemoveQueuedEvents( aThread: TThread; aMethod: TThreadMethod);
"The given method" can either refer to
- "aMethod", which is a variable containing a code reference, AND an instance
- the code reference contained in "aMethod"
Currently the 2nd applies (and appears to also be "what Delphi does"). // Ondrej edit: Delphi compares both Code and Data pointers
The documentation should be reworded, to make it more clear that the value of the instance passed in as part of the parameters fulfils no purpose and is ignored.
----------
While it could be inferred from the fact that "calls to" do not care about arguments passed to the callee, this "hint" seems very subtle compared to the fact that half of a parameter passed to RemoveQueuedEvents is ignored.
Steps to reproduce:
program Project1;
{$ifdef fpc}
{$mode delphi}
{$Macro on}
{$Define AtomicIncrement:=InterlockedIncrement}
{$Define AtomicDecrement:=InterlockedDecrement}
{$else}
{$APPTYPE CONSOLE}
{$endif}
uses
{$IFDEF UNIX} cthreads, {$ENDIF} Classes;
type
TMyClass = class
public
ThreadID, ClassID: Integer;
procedure Foo;
end;
TMyThread = class(TThread)
private
ID: Integer;
c1, c2: TMyClass;
public
procedure Execute; override;
constructor Create(const AID: Integer);
destructor Destroy; override;
end;
var
i: integer;
constructor TMyThread.Create(const AID: Integer);
begin
AtomicIncrement(i);
ID := AID;
FreeOnTerminate := False;
c1 := TMyClass.Create;
c1.ThreadID := ID;
c1.ClassID := 1;
c2 := TMyClass.Create;
c2.ThreadID := ID;
c2.ClassID := 2;
inherited Create(False);
end;
destructor TMyThread.Destroy;
begin
c1.Free;
c2.Free;
inherited Destroy;
end;
procedure TMyThread.Execute;
begin
Queue(self, c1.Foo);
Queue(self, c2.Foo);
Sleep(500);
case ID of
1: RemoveQueuedEvents(Self, c1.Foo);
2: RemoveQueuedEvents(nil, c1.Foo);
3: RemoveQueuedEvents(Self, nil);
end;
AtomicDecrement(i);
end;
procedure TMyClass.Foo;
begin
writeln('In Foo: ThreadID=', ThreadID, ', ClassID=', ClassID);
end;
var
t1, t2, t3: TMyThread;
begin
i := 0;
t1 := TMyThread.Create(1);
t2 := TMyThread.Create(2);
t3 := TMyThread.Create(3);
while i > 0 do ;
CheckSynchronize();
ReadLn;
t1.Free;
t2.Free;
t3.Free;
end.
---
Delphi output:
In Foo: ThreadID=2, ClassID=2
---
FPC: output:
// nothing -- FPC deletes too much
Additional information:
See also https://lists.freepascal.org/pipermail/fpc-devel/2020-September/043165.html and replies
Mantis conversion info:
- Mantis ID: 37819
- OS: win 10
- OS Build: 10
- Platform: 64bit Intel
- Version: 3.2.0
- Fixed in revision: 1755 (#db509454)