Browse Source

* Verify correctness of timer objects

Michaël Van Canneyt 2 weeks ago
parent
commit
e59ed178da
1 changed files with 53 additions and 5 deletions
  1. 53 5
      packages/wasm-utils/src/wasm.timer.objects.pas

+ 53 - 5
packages/wasm-utils/src/wasm.timer.objects.pas

@@ -20,9 +20,9 @@ interface
 
 
 uses
 uses
 {$IFDEF FPC_DOTTEDUNITS}
 {$IFDEF FPC_DOTTEDUNITS}
-  System.Classes, System.SysUtils,
+  System.Classes, System.SysUtils, System.SyncObjs,
 {$ELSE}
 {$ELSE}
-  Classes, SysUtils,
+  Classes, SysUtils, SyncObjs,
 {$ENDIF}
 {$ENDIF}
   wasm.timer.api, wasm.timer.shared;
   wasm.timer.api, wasm.timer.shared;
 
 
@@ -76,6 +76,41 @@ uses wasm.logger.api;
 resourcestring
 resourcestring
   SErrCouldNotCreateTimer = 'Could not create timer';
   SErrCouldNotCreateTimer = 'Could not create timer';
 
 
+var
+  ActiveTimers : TFPList;
+  Lock : TCriticalSection;
+
+procedure AddTimer(aTimer : TWasmTimer);
+begin
+  Lock.Enter;
+  try
+    ActiveTimers.Add(aTimer);
+  finally
+    Lock.Leave
+  end;
+end;
+
+function ValidTimer(aTimer : TWasmTimer): boolean;
+begin
+  Lock.Enter;
+  try
+    Result:=ActiveTimers.IndexOf(aTimer)<>-1;
+  finally
+    Lock.Leave;
+  end;
+end;
+
+procedure RemoveTimer(aTimer : TWasmTimer);
+
+begin
+  Lock.Enter;
+  try
+    ActiveTimers.Remove(aTimer);
+  finally
+    Lock.Leave;
+  end;
+end;
+
 constructor TWasmTimer.Create(aInterval: Integer; aEvent: TNotifyEvent; aSender: TObject);
 constructor TWasmTimer.Create(aInterval: Integer; aEvent: TNotifyEvent; aSender: TObject);
 begin
 begin
   FOnTimer:=aEvent;
   FOnTimer:=aEvent;
@@ -87,17 +122,21 @@ begin
     __wasmtimer_log(wllError,SErrCouldNotCreateTimer);
     __wasmtimer_log(wllError,SErrCouldNotCreateTimer);
     Raise EWasmTimer.Create(SErrCouldNotCreateTimer);
     Raise EWasmTimer.Create(SErrCouldNotCreateTimer);
     end;
     end;
+  AddTimer(Self);
 end;
 end;
 
 
 destructor TWasmTimer.Destroy;
 destructor TWasmTimer.Destroy;
 begin
 begin
+  FOnTimer:=Nil;
+  RemoveTimer(Self);
   __wasm_timer_deallocate(FID);
   __wasm_timer_deallocate(FID);
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
 procedure TWasmTimer.Execute;
 procedure TWasmTimer.Execute;
 begin
 begin
-  FOnTimer(FSender);
+  if assigned(FOnTimer) then
+    FOnTimer(FSender);
 end;
 end;
 
 
 class procedure TWasmTimer.HandleWasmTimer(aTimerID: TWasmTimerID; userdata: pointer; var aContinue: Boolean);
 class procedure TWasmTimer.HandleWasmTimer(aTimerID: TWasmTimerID; userdata: pointer; var aContinue: Boolean);
@@ -107,7 +146,7 @@ var
 
 
 begin
 begin
   __wasmtimer_log(wllTrace, 'Timer(ID: %d) tick. Data [%p]',[aTimerID,UserData]);
   __wasmtimer_log(wllTrace, 'Timer(ID: %d) tick. Data [%p]',[aTimerID,UserData]);
-  aContinue:=(Obj.FID=aTimerID);
+  aContinue:=ValidTimer(Obj) and (Obj.FID=aTimerID);
   __wasmtimer_log(wllDebug, 'Timer(id: %d) tick. Data [%p] continue: %b',[aTimerID,UserData,aContinue]);
   __wasmtimer_log(wllDebug, 'Timer(id: %d) tick. Data [%p] continue: %b',[aTimerID,UserData,aContinue]);
   if aContinue then
   if aContinue then
     Obj.Execute;
     Obj.Execute;
@@ -149,7 +188,7 @@ end;
 procedure TTimer.DoOnTimer(Sender : TObject);
 procedure TTimer.DoOnTimer(Sender : TObject);
 
 
 begin
 begin
-  If Assigned(FOnTimer) then
+  If FEnabled and Assigned(FOnTimer) then
     FOnTimer(Self);
     FOnTimer(Self);
 end;
 end;
 
 
@@ -175,11 +214,20 @@ end;
 
 
 destructor TTimer.Destroy;
 destructor TTimer.Destroy;
 begin
 begin
+  OnTimer:=Nil;
   Enabled:=False;
   Enabled:=False;
+
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
 initialization
 initialization
+  ActiveTimers:=TFPList.Create;
+  Lock:=TCriticalSection.Create;
   OnWasmTimerTick:[email protected]
   OnWasmTimerTick:[email protected]
+
+finalization
+  OnWasmTimerTick:=Nil;
+  FreeAndNil(ActiveTimers);
+  FreeAndNil(Lock);
 end.
 end.