[fpc-devel] Threads not working in console application

2007-12-06 Thread Graeme Geldenhuys
Hi,

I've created a while back a thread based Timer.  At the time I
developed the timer, I tested it in a Lazarus (LCL) GUI application
and everything worked perfectly. Just tested it now and it still works
fine.

Today I tried to use that Timer in a Console application and a fpGUI
based application and the timer doesn't work for some reason!  I'm
using FPC 2.2.0 under Linux.

I attached a Console test project and the threadtimer.pas unit.  Has
anybody got any ideas as to why it doesn't work in a console app?

BTW:
To get the console app to continue running, I have a loop checking for
a file or sleeps for 500 ms.  The timer is enabled before that loop
starts, so I am supposed to see output to the console.  I added some
debug writeln()'s to know when the time starts or stops and which
events file (application loop or timer event).

Regards,
  - Graeme -


___
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/
{
  A basic thread based timer component. Can be used in GUI and non-GUI apps.
  Author:  Graeme Geldenhuys
}
unit ThreadTimer;

{$mode objfpc}{$H+}

interface

uses
  Classes;

type
  TFPTimer = class; // forward declaration


  TFPTimerThread = class(TThread)
  private
FTimer: TFPTimer;
  protected
procedure   DoExecute;
procedure   Execute; override;
  public
constructor CreateTimerThread(Timer: TFPTimer);
  end;


  TFPTimer = class(TComponent)
  private
FInterval: Integer;
FPriority: TThreadPriority;
FOnTimer: TNotifyEvent;
FContinue: Boolean;
FRunning: Boolean;
FEnabled: Boolean;
procedure   SetEnabled(Value: Boolean );
  protected
procedure   StartTimer;
procedure   StopTimer;
propertyContinue: Boolean read FContinue write FContinue;
  public
constructor Create(AOwner: TComponent); override;
destructor  Destroy; override;
procedure   On;
procedure   Off;
  published
propertyEnabled: Boolean read FEnabled write SetEnabled;
propertyInterval: Integer read FInterval write FInterval;
propertyThreadPriority: TThreadPriority read FPriority write FPriority default tpNormal;
propertyOnTimer: TNotifyEvent read FOnTimer write FOnTimer;
  end;


implementation

uses
  SysUtils;
  
{ No need to pull in the Windows unit. Also this works on all platforms. }
function _GetTickCount: Cardinal;
begin
  Result := Cardinal(Trunc(Now * 24 * 60 * 60 * 1000));
end;


{ TFPTimerThread }

constructor TFPTimerThread.CreateTimerThread(Timer: TFPTimer);
begin
  inherited Create(True);
  FTimer := Timer;
  FreeOnTerminate := True;
end;

procedure TFPTimerThread.Execute;
var
  SleepTime: Integer;
  Last: Cardinal;
begin
  while FTimer.Continue do
  begin
Last := _GetTickCount;
Synchronize(@DoExecute);
SleepTime := FTimer.FInterval - (_GetTickCount - Last);
if SleepTime  10 then
  SleepTime := 10;
Sleep(SleepTime);
  end;
end;

procedure TFPTimerThread.DoExecute;
begin
  if Assigned(FTimer.OnTimer) then FTimer.OnTimer(FTimer);
end;


{ TFPTimer }

constructor TFPTimer.Create(AOwner: TComponent);
begin
  inherited;
  FPriority := tpNormal;
end;

destructor TFPTimer.Destroy;
begin
  StopTimer;
  inherited Destroy;
end;

procedure TFPTimer.SetEnabled(Value: Boolean);
begin
  if Value  FEnabled then
  begin
FEnabled := Value;
if FEnabled then
  StartTimer
else
  StopTimer;
  end;
end;

procedure TFPTimer.StartTimer;
begin
  if FRunning then
Exit; //==
  FContinue := True;
  if not (csDesigning in ComponentState) then
  begin
with TFPTimerThread.CreateTimerThread(Self) do
begin
  Priority := FPriority;
  Resume;
end;
  end;
  FRunning := True;
  writeln('StartTimer');// debug line
end;

procedure TFPTimer.StopTimer;
begin
  writeln('StopTimer'); // debug line
  FContinue := False;
  FRunning  := False;
end;

procedure TFPTimer.On;
begin
  StartTimer;
end;

procedure TFPTimer.Off;
begin
  StopTimer;
end;

end.



test.lpr
Description: Binary data
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Threads not working in console application

2007-12-06 Thread Yury Sidorov

From: Graeme Geldenhuys [EMAIL PROTECTED]

Hi,

I've created a while back a thread based Timer.  At the time I
developed the timer, I tested it in a Lazarus (LCL) GUI application
and everything worked perfectly. Just tested it now and it still 
works

fine.

Today I tried to use that Timer in a Console application and a fpGUI
based application and the timer doesn't work for some reason!  I'm
using FPC 2.2.0 under Linux.

I attached a Console test project and the threadtimer.pas unit.  Has
anybody got any ideas as to why it doesn't work in a console app?

BTW:
To get the console app to continue running, I have a loop checking 
for

a file or sleeps for 500 ms.  The timer is enabled before that loop
starts, so I am supposed to see output to the console.  I added some
debug writeln()'s to know when the time starts or stops and which
events file (application loop or timer event).


The thread itself works, but not Synchronize() method.
You need to call CheckSynchronize inside main loop.

Yury. 
___

fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Threads not working in console application

2007-12-06 Thread Michael Van Canneyt


On Thu, 6 Dec 2007, Graeme Geldenhuys wrote:

 Hi,
 
 I've created a while back a thread based Timer.  At the time I
 developed the timer, I tested it in a Lazarus (LCL) GUI application
 and everything worked perfectly. Just tested it now and it still works
 fine.
 
 Today I tried to use that Timer in a Console application and a fpGUI
 based application and the timer doesn't work for some reason!  I'm
 using FPC 2.2.0 under Linux.

As far as I can see, you forget to call checksynchronize in the main thread.

BTW. There is a TThreadedTimer in the FCL, based on your code.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Threads not working in console application

2007-12-06 Thread Graeme Geldenhuys
On 06/12/2007, Michael Van Canneyt [EMAIL PROTECTED] wrote:

 As far as I can see, you forget to call checksynchronize in the main thread.


Thanks Michael

 BTW. There is a TThreadedTimer in the FCL, based on your code.

I guess it didn't make it into FPC 2.2.0 as I searched all the sources
and couldn't find any such class.


Regards,
  - Graeme -


___
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Threads not working in console application

2007-12-06 Thread Graeme Geldenhuys
On 06/12/2007, Yury Sidorov [EMAIL PROTECTED] wrote:

 The thread itself works, but not Synchronize() method.
 You need to call CheckSynchronize inside main loop.


Ah, thanks Yury!  That also means that having the main loop fire every
500ms (it was just a test for the console app), my timer cannot fire
it's events in less than 500ms (eg: timer.Interval := 200).

  while True do
  begin
if FileExists('killme') then
  break;
Sleep(500);
CheckSynchronize;
writeln('event loop');
  end;


As a test, I set the main loop's Sleep() to 10ms and the app didn't
even register in 'top' for CPU usage, so I guess it's ok to set
sleep() with such a small time?
Not that I intend to use the Timer interval for 500ms though.


I'll read up no CheckSyncronize to get a better understanding of this...


Regards,
  - Graeme -


___
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Threads not working in console application

2007-12-06 Thread Michael Van Canneyt


On Thu, 6 Dec 2007, Graeme Geldenhuys wrote:

 On 06/12/2007, Michael Van Canneyt [EMAIL PROTECTED] wrote:
 
  As far as I can see, you forget to call checksynchronize in the main thread.
 
 
 Thanks Michael
 
  BTW. There is a TThreadedTimer in the FCL, based on your code.
 
 I guess it didn't make it into FPC 2.2.0 as I searched all the sources
 and couldn't find any such class.

Hm. It should be. Unit fptimer.pp. 

Of course, if you used the TThreadedTimer name, it won't work. 
look for TFPThreadedTimerDriver. I generalized the architecture a bit.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel