That does not make sense. Destroy is called after the terminate ( or Terminated := True )Yep, these are all problems in unPrincipal.pas.
The immediate problem is in TTheThread.Execute where he calls OnTerminate without assigning anything to it.I deleted the call to OnTerminate(self) in TTheThread.Execute but for me the code still crashed in TScheduledEvent.Stop;.
I did not try to compile it. But after reading your post I did the few obvious changes including changing "Stop Thread" and a quick test seemed to run. Waited a few seconds after hitting "Start Thread" then "Stop Thread" waited more. Closed the app. No crash.Ok, for topicstarters information: Are you compiling and running on Windows of Linux?
destructor TTheThread.Destroy; begin if Assigned(FScheduleTaskList) then FreeAndNil(FScheduleTaskList); if Assigned(FKnowTasks) then FreeAndNil(FKnowTasks); Self.Terminate; inherited Destroy; end;
That does not make sense. Destroy is called after the terminate ( or Terminated := True )
I did not try to compile it. But after reading your post I did the few obvious changes including changing "Stop Thread" and a quick test seemed to run. Waited a few seconds after hitting "Start Thread" then "Stop Thread" waited more. Closed the app. No crash.Ok, for topicstarters information: Are you compiling and running on Windows of Linux?
(I still find it strange that all those MSWINDOWS/FPC IFDEFs are really mixed up in Cromis.Scheduler.pas)
I did not try to compile it. But after reading your post I did the few obvious changes including changing "Stop Thread" and a quick test seemed to run. Waited a few seconds after hitting "Start Thread" then "Stop Thread" waited more. Closed the app. No crash.Ok, for topicstarters information: Are you compiling and running on Windows of Linux?
(I still find it strange that all those MSWINDOWS/FPC IFDEFs are really mixed up in Cromis.Scheduler.pas)
I believe the event is being signaled correctly, so much so that the event is triggered, so this is working, right?That line shows that when using FPC (which we are) the RTLEventSetEvent() is used with FTermEvent.
{$ IFDEF FPC} RTLEventSetEvent {$ ELSE} SetEvent {$ ENDIF} (@ FTermEvent);
diff --git "a/C:\\Users\\Rik\\Downloads\\cromis original\\testeCromis\\cromis\\Cromis.Scheduler.pas" "b/C:\\Users\\Rik\\Downloads\\testeCromis\\cromis\\Cromis.Scheduler.pas"
index ae75dbc..eb9d403 100644
--- "a/C:\\Users\\Rik\\Downloads\\New folder (2)\\testeCromis\\cromis\\Cromis.Scheduler.pas"
+++ "b/C:\\Users\\Rik\\Downloads\\testeCromis\\cromis\\Cromis.Scheduler.pas"
@@ -1068,9 +1068,9 @@ begin
FRunning := False;
// set the terminate event, so that the thread can safely exit
- {$IFDEF FPC}RTLEventSetEvent{$ELSE}SetEvent{$ENDIF}(@FTermEvent);
+ {$IFNDEF MSWINDOWS}RTLEventSetEvent{$ELSE}SetEvent{$ENDIF}(FTermEvent);
- {$IFNDEF FPC}
+ {$IFDEF MSWINDOWS}
// wait and block until the scheduling thread is finished
AResult := WaitForSingleObject(FSchThread.Handle, cShutdownTimeout);
@@ -1084,7 +1084,7 @@ begin
{$ENDIF}
// close the event handle and free the thread
- {$IFDEF FPC}RTLEventDestroy{$ELSE}CloseHandle{$ENDIF}(@FTermEvent);
+ {$IFNDEF MSWINDOWS}RTLEventDestroy{$ELSE}CloseHandle{$ENDIF}(FTermEvent);
FreeAndNil(FSchThread);
// fire the on schedule stop event
--- testeCromis.org/cromis/Cromis.Scheduler.pas zo feb 11 01:56:48 2018
+++ testeCromis/cromis/Cromis.Scheduler.pas ma feb 12 17:15:50 2018
@@ -1071 +1071 @@ begin
- {$IFDEF FPC}RTLEventSetEvent{$ELSE}SetEvent{$ENDIF}(@FTermEvent);
+ {$IFNDEF MSWINDOWS}RTLEventSetEvent(@FTermEvent){$ELSE}SetEvent(FTermEvent){$ENDIF};
@@ -1073 +1073 @@ begin
- {$IFNDEF FPC}
+ {$IFDEF MSWINDOWS}
@@ -1087 +1087 @@ begin
- {$IFDEF FPC}RTLEventDestroy{$ELSE}CloseHandle{$ENDIF}(@FTermEvent);
+ {$IFNDEF MSWINDOWS}RTLEventDestroy(@FTermEvent){$ELSE}CloseHandle(FTermEvent){$ENDIF};
--- testeCromis.org/unprincipal.pas zo feb 11 13:06:35 2018
+++ testeCromis/unprincipal.pas ma feb 12 17:23:45 2018
@@ -71,0 +72 @@ end;
+ procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
@@ -164 +165 @@ begin
- ThreadTeste.FreeOnTerminate := True;
+ ThreadTeste.FreeOnTerminate := false;
@@ -173,0 +175,10 @@ end;
+procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
+begin
+ if Assigned(ThreadTeste) then
+ begin
+ ThreadTeste.Terminate;
+ ThreadTeste.WaitFor;
+ ThreadTeste.Free;
+ end;
+end;
+
@@ -208 +219 @@ begin
- Self.Terminate;
+ //Self.Terminate;
@@ -214 +225 @@ begin
- try
+ //try
@@ -216,2 +227,2 @@ begin
- LoadCronTab;
- DisplayCronInfo;
+ Synchronize(@LoadCronTab);
+ Synchronize(@DisplayCronInfo);
@@ -220,3 +231,3 @@ begin
- finally
- OnTerminate(self);
- end;
+ //finally
+ // OnTerminate(self);
+ //end;
First lets clear the IFDEFS issue. They were added quite some time ago as someone asked me for a Linux FPC support. So I added it. I don't think I tested any of it in full extent. Under Delphi and Windows the unit is tested and use in production environment daily.Yes, for Delphi under Windows and FPC under Linux the IFDEFs are fine. But for FPC under Windows it is not. For example, like I already said, the IFDEFs for MSWINDOWS and FPC are mixed (MSWINDOWS is also defined in FPC for Windows). The result is that FTermEvent is a THandle and it is created with CreateEvent (for Windows) but in .Stop there are several calls to RTLEvent because FPC is used in the define. Look for all FPC} in the source. They should NOT be there for FPC under Windows because FTermEvent is already a THandle due to the IFDEF MSWINDOWS.
But looking over the IFDEFS at a glance I think they are correct. Basically the idea is to call windows API calls like SetEvent, WaitForSingleObject etc under Windows and Linux conterparts (RTL*) under Linux. So using {$IFDEF WINDOWS} seems correct to me.
First lets clear the IFDEFS issue. They were added quite some time ago as someone asked me for a Linux FPC support. So I added it. I don't think I tested any of it in full extent. Under Delphi and Windows the unit is tested and use in production environment daily.Yes, for Delphi under Windows and FPC under Linux the IFDEFs are fine. But for FPC under Windows it is not. For example, like I already said, the IFDEFs for MSWINDOWS and FPC are mixed (MSWINDOWS is also defined in FPC for Windows). The result is that FTermEvent is a THandle and it is created with CreateEvent (for Windows) but in .Stop there are several calls to RTLEvent because FPC is used in the define. Look for all FPC} in the source. They should NOT be there for FPC under Windows because FTermEvent is already a THandle due to the IFDEF MSWINDOWS.
But looking over the IFDEFS at a glance I think they are correct. Basically the idea is to call windows API calls like SetEvent, WaitForSingleObject etc under Windows and Linux conterparts (RTL*) under Linux. So using {$IFDEF WINDOWS} seems correct to me.
I've created a patch where all IFDEF FPC is changed to IFNDEF MSWINDOWS (and IFNDEF FPC in IFDEF MSWINDOWS). In that case, for FPC under Windows the Windows-events are used and for FPC under Linux the RTLEvents are used.
Note: Under FPC for Windows both MSWINDOWS and FPC are defined. So use one or the other but don't mix them. If the source should run under Delphi for OSX or LINUX then you've got another problem but I don't think that's a target
I'm just having the error if I try to kill the main Thread, from TForm1, can you attach your whole code?I already showed you a patch of what I changed. I didn't change anything else.
But, I did not check the Thread GUI, IThreadTeste is NOT the main thread. The application itself (TApplication and the main form) is the main thread. Any other thread you use is another thread. Accessing components in any thread that are in other threads need to be done via Synchronize or Queue.
property ThreadTeste: TTheThread ......
as "main thread".