Recent

Author Topic: Random freeze with fpTimer  (Read 23643 times)

Tharon

  • Jr. Member
  • **
  • Posts: 61
Random freeze with fpTimer
« on: February 03, 2015, 05:44:40 pm »
Hello, i'm having a strange and somewhat inexplicable issue with ftpTimer.

When i disable it, stop it with the StopTimer procedure, of Free it, there is a change it will freeze and hang  the whole application.
I've searched everywhere but wasn't capable to find a solution to it.

This is a small code that reproduce the problem :

Code: [Select]
var
  Form1: TForm1;
  MainTimer : TfpTimer;

implementation

{$R *.lfm}

{ TForm1 }


procedure TForm1.CheckOnTimer(Sender: TObject);
begin
  Label4.Caption := IntToStr(GetTickCount());
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  MainTimer := TFpTimer.Create(Nil);
  MainTimer.OnTimer := @CheckOnTimer;
  MainTimer.Interval := 1000;
  MainTimer.StartTimer;
end;

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  MainTimer.StopTimer;   // Freeze it on random occasions
  MainTimer.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  If MainTimer.Enabled = True Then MainTimer.StopTimer  // Turn the timer on or off, freeze it on random occasions
  Else MainTimer.StartTimer;
end;       

End. 

Maybe there is something i'm missing, but i'm really out of ideas.

ChrisF

  • Hero Member
  • *****
  • Posts: 542

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Random freeze with fpTimer
« Reply #2 on: February 03, 2015, 11:47:57 pm »
Yes, i've already read that topic, but it doesn't apply in my case because i do not stop or disable the timer inside its thread.

If you read my code, i stop the timer in the main thread, and not inside the ontimer.

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Random freeze with fpTimer
« Reply #3 on: February 04, 2015, 12:27:26 am »
I don't know FPTimers, but I guess that trying to free the timer (MainTimer.Free) without being sure that the timer thread has finished (MainTimer.StopTimer -> TFPTimerThread.Execute) may lead to unexpected results.

** EDIT ** Or eventually when the whole application is closing (it may depends of your version of windows). Theoretically, threads are supposed to be closed properly (i.e. wait for thread task to be over).
« Last Edit: February 04, 2015, 12:35:30 am by ChrisF »

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Random freeze with fpTimer
« Reply #4 on: February 04, 2015, 04:29:08 am »
The default timer driver TFPThreadedTimerDriver has a bug: It creates a thread that has FreeOnTerminate = true and later on it touches it freely.

I suggest not to set FreeOnTerminate to true when creating TFPTimerThread:
Code: [Select]
constructor TFPTimerThread.CreateTimerThread(ATimerDriver: TFPTimerDriver);
begin
  inherited Create(True);
  FTimerDriver:=ATimerDriver;
  //FreeOnTerminate := True; <----
end;

And changing StopTimer to:
Code: [Select]
Procedure TFPThreadedTimerDriver.StopTimer;
begin
  FThread.FTimerDriver:=Nil;
  FThread.Free;
  FThread := nil;
end;

Notice that FThread.Free will call both Terminate and WaitFor.

Please test using the attached fptimer.pp. To test simply put it in your project folder.

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Random freeze with fpTimer
« Reply #5 on: February 04, 2015, 11:21:12 am »
Thank you engkin, i'll test it asap.

Anyway, i made further test last night and discovered the culprit, is an instruction in FPThreadedTimerDriver.StopTimer;     

Code: [Select]
  If Assigned(FThread) then
    Fthread.WaitFor; 

Removing it will solve the problem, but i don't know if it can cause further issues. In your code you too have removed it, but also added some other instructions.
« Last Edit: February 04, 2015, 01:10:37 pm by Tharon »

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Random freeze with fpTimer
« Reply #6 on: February 04, 2015, 03:59:14 pm »
Ok engkin, i've tested your code and seems to work well. I didn't had any freeze or memory leak until now.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Random freeze with fpTimer
« Reply #7 on: February 04, 2015, 04:15:37 pm »
Anyway, i made further test last night and discovered the culprit, is an instruction in FPThreadedTimerDriver.StopTimer;     

Code: [Select]
  If Assigned(FThread) then
    Fthread.WaitFor; 

Removing it will solve the problem, but i don't know if it can cause further issues. In your code you too have removed it, but also added some other instructions.

Yes, that's one of the places where it touches the thread which is not safe. This call has a higher probability to cause a problem because it comes directly after Terminate and CheckSynchronize.

Keeping this call and changing FThread.FreeOnTerminate to false at the beginning of this procedure will prevent it from freezing. But still that is not safe. If it were up to me, FreeOnTerminate = true should not be used. I had seen it causing problems over and over again.

Edit:
Are you one Windows or Linux?
« Last Edit: February 04, 2015, 04:23:49 pm by engkin »

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Random freeze with fpTimer
« Reply #8 on: February 04, 2015, 06:21:00 pm »
I'm on windows.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Random freeze with fpTimer
« Reply #9 on: February 04, 2015, 07:40:48 pm »
An identical patch was posted in 2010 to solve this same problem. But for some reason it was not accepted and it seems like there is a mysterious reason to keep FreeOnTerminate = True.

Not to break working code, we might have to keep CheckSynchronize call. Although I don't think it should be part of the timer.

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Random freeze with fpTimer
« Reply #10 on: February 05, 2015, 02:30:19 am »
Really Strange. In the current version fpTimer is totally unreliable on windows, or at least on my system.

Anyway, your patch seems to work well. I'm using it for a joypad to keyboard emulator with multiple profiles, with six different timer being in use and frequently disabled and enabled.
Until now i didn't have any freeze, crash or memory leak.
« Last Edit: February 05, 2015, 02:33:39 am by Tharon »

valdir.marcos

  • Hero Member
  • *****
  • Posts: 1285
Re: Random freeze with fpTimer
« Reply #11 on: February 05, 2015, 03:25:03 am »
I have request some extra help on other topic more specific about patches and bug solving:
http://forum.lazarus.freepascal.org/index.php/topic,25820.msg168366/topicseen.html#new

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Random freeze with fpTimer
« Reply #12 on: February 05, 2015, 03:58:40 am »
@Tharon, great! Thanks for the feedback.

@valdir.marcos, good idea. Thank you.

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Random freeze with fpTimer
« Reply #13 on: February 07, 2015, 01:35:05 pm »
Sorry, but i have to report that fptimer seems to be still unsafe.

Freeze issues are quite rare with the fix, but still happens.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Random freeze with fpTimer
« Reply #14 on: February 07, 2015, 02:20:54 pm »
Thanks for reporting. It is good to know the timer is not safe yet.

 

TinyPortal © 2005-2018