From: <ob...@us...> - 2006-07-04 12:15:29
|
Revision: 10781 Author: obones Date: 2006-07-04 05:15:22 -0700 (Tue, 04 Jul 2006) ViewCVS: http://svn.sourceforge.net/jvcl/?rev=10781&view=rev Log Message: ----------- Using Suspend/Resume is in no way reliable, introduced the Paused property that works better with a critical section Modified Paths: -------------- trunk/jvcl/run/JvTimer.pas Modified: trunk/jvcl/run/JvTimer.pas =================================================================== --- trunk/jvcl/run/JvTimer.pas 2006-07-03 16:55:25 UTC (rev 10780) +++ trunk/jvcl/run/JvTimer.pas 2006-07-04 12:15:22 UTC (rev 10781) @@ -86,7 +86,7 @@ implementation uses - Forms, Consts, + Forms, Consts, SyncObjs, JvJVCLUtils; //=== { TJvTimerThread } ===================================================== @@ -97,20 +97,27 @@ FOwner: TJvTimer; FInterval: Cardinal; FException: Exception; + FPaused: Boolean; + FPauseSection: TCriticalSection; procedure HandleException; + procedure SetPaused(const Value: Boolean); protected procedure Execute; override; public constructor Create(Timer: TJvTimer; Enabled: Boolean); + destructor Destroy; override; {$IFDEF CLR} procedure Synchronize(Method: TThreadMethod); {$ENDIF CLR} property Terminated; + + property Paused: Boolean read FPaused write SetPaused; end; constructor TJvTimerThread.Create(Timer: TJvTimer; Enabled: Boolean); begin FOwner := Timer; + FPauseSection := TCriticalSection.Create; inherited Create(not Enabled); FInterval := 1000; FreeOnTerminate := False; @@ -122,6 +129,26 @@ Application.HandleException(Self); end; +procedure TJvTimerThread.SetPaused(const Value: Boolean); +begin + if FPaused <> Value then + begin + FPaused := Value; + + if FPaused then + begin + FPauseSection.Acquire; + + if Suspended then + Resume; + end + else + begin + FPauseSection.Release; + end; + end; +end; + {$IFDEF CLR} procedure TJvTimerThread.Synchronize(Method: TThreadMethod); begin @@ -129,6 +156,13 @@ end; {$ENDIF CLR} +destructor TJvTimerThread.Destroy; +begin + FPauseSection.Free; + + inherited Destroy; +end; + procedure TJvTimerThread.Execute; function ThreadClosed: Boolean; @@ -146,12 +180,18 @@ begin repeat - if not ThreadClosed and (SleepEx(FInterval, False) = 0) and - not ThreadClosed and FOwner.FEnabled then + FPauseSection.Acquire; + + if not ThreadClosed and not ThreadClosed and FOwner.FEnabled then + begin with FOwner do + begin if SyncEvent then + begin Synchronize(Timer) + end else + begin try Timer; except @@ -161,6 +201,13 @@ HandleException; end; end; + end; + end; + end; + + FPauseSection.Release; + + SleepEx(FInterval, False); until Terminated; end; @@ -186,9 +233,9 @@ FEnabled := False; FOnTimer := nil; {TTimerThread(FTimerThread).FOwner := nil;} + FTimerThread.Terminate; while FTimerThread.Suspended do FTimerThread.Resume; - FTimerThread.Terminate; FTimerThread.Free; FTimer.Free; inherited Destroy; @@ -199,16 +246,19 @@ if FThreaded then begin FreeAndNil(FTimer); - if not FTimerThread.Suspended then - FTimerThread.Suspend; + (FTimerThread as TJvTimerThread).Paused := True; +{ if not FTimerThread.Suspended then + FTimerThread.Suspend;} TJvTimerThread(FTimerThread).FInterval := FInterval; if (FInterval <> 0) and FEnabled and Assigned(FOnTimer) then begin {$IFDEF MSWINDOWS} FTimerThread.Priority := FThreadPriority; {$ENDIF MSWINDOWS} - while FTimerThread.Suspended do - FTimerThread.Resume; + + (FTimerThread as TJvTimerThread).Paused := False; +(* while FTimerThread.Suspended do + FTimerThread.Resume;*) end; end else This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |