Recent

Author Topic: Getting started with a service (LazDaemon)  (Read 45189 times)

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Getting started with a service (LazDaemon)
« Reply #15 on: June 04, 2013, 06:35:00 pm »

IMHO, there is nothing to patch.

According to all your tests, it seems now that Windows 8 kills all the remaining active threads when a service stops, while Windows XP doesn't.

So, you should end your service only when your thread has really ended.

The simplest way would be to wait a little bit (i.e. sleep(a_given_time_in_ms)), but it's not recommended inside the start/stop procedures of a windows service.

The best way is to use a event for that. As I've recently discovered in another topic of this forum that there is an object for events within FPC, here is how to modified my former sample code (you could also use the Windows API directly, though it's of course less portable).

Attached, a modified version of my sample 3, using only TCustomDaemon, TThread and RTLEvent  (no more any windows API calls).

Here is my results:
Code: [Select]
18:14:14: Daemon Install: -1
18:14:35: Daemon Start: -1
18:14:35: Daemon Execute: 0
18:14:35: Beginning of thread
18:14:36: Tick : 1
18:14:37: Tick : 2
...
18:14:45: Tick : 10
18:14:46: Daemon Stop: -1
18:14:46: Calling Thread End
18:14:46: Waiting for Thread End...
18:14:46: Tick : 11
18:14:46: End of thread
18:14:46: Thread End Got  ->  Exit
18:15:08: Daemon UnInstall: -1

It should also work for you too (well, at least theoretically).

If it does, just be sure to call the 'RTLEventSetEvent' function at the very end of your main thread procedure/function (i.e. it should always be the last line of code for this procedure).

mdalacu

  • Full Member
  • ***
  • Posts: 233
    • dmSimpleApps
Re: Getting started with a service (LazDaemon)
« Reply #16 on: June 05, 2013, 11:31:57 am »
Thank you very much. It works! I will adapt my program with this solution.
 :D

mdalacu

  • Full Member
  • ***
  • Posts: 233
    • dmSimpleApps
Re: Getting started with a service (LazDaemon)
« Reply #17 on: June 07, 2013, 12:11:27 pm »
A unrelated question: Can i write to system log from the working thread? It always crashes, but if i write from a daemon method it works.
Code: [Select]
procedure TWorkingThread.Execute;
begin
...
Daemon1.EventLog1.Info('Tick.');  <-- Crashes!!!
end;

procedure TDaemon1.DataModuleStart(Sender: TCustomDaemon; var OK: Boolean);
begin
...
  EventLog1.LogType:=ltSystem;
  EventLog1.Active:=True;
  EventLog1.RegisterMessageFile('');
  EventLog1.Resume;
  EventLog1.Log('Service Started!');  <-- It works just fine!
end;

How can i modify my code to make it work? Thank you.

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Getting started with a service (LazDaemon)
« Reply #18 on: June 07, 2013, 07:49:40 pm »
Honestly, 'till there "Application.Log" has been quite enough for me (for a sample to how to use it, see daemon2.zip in this topic).

Otherwise, you can try to put your EventLog object into your daemon class. This event may then be reached inside the thread code, via the Parent property of the thread. See attached sample (i.e. "daemon3-withEventLog.zip).

It's possible that it's not working for more recent versions of windows; but it does for me...

**Edit **: I've wrongly used EventLog.Log instead of EventLog.Info inside the thread code in my sample; but, after retesting, both of them are working anyway.
« Last Edit: June 07, 2013, 07:55:25 pm by ChrisF »

mdalacu

  • Full Member
  • ***
  • Posts: 233
    • dmSimpleApps
Re: Getting started with a service (LazDaemon)
« Reply #19 on: June 08, 2013, 08:18:19 pm »
Thank you ChrisF very much for your answer. As soon as i will be able to test this i will post back results. I have written 3 multi threaded apps by now and the "parent" thing still eludes me ...  :o
As a side note, i have observed that EvenLog does not write to sistem log on windows (only file log) in builds newer than 1.0.8 (the one included with Code Typhoon 4.20 and 4.30).

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Getting started with a service (LazDaemon)
« Reply #20 on: June 10, 2013, 03:11:09 am »
Of course, there are not any 'parent' notions if you consider only the threads themselves.

It's just that within the sample coming from Lazarus/FPC, the TThread object has been encapsulated into the TDaemon object. But, it's not mandatory.

To comply the object rules, and to stick to the sample conception, I've also used object code in my former samples. But once again, you don't HAVE to.

So, in my samples, I've added a parent property into my own inherited Thread class (affected with the SetParent method), just to be able to reach easily the TDaemon (i.e. the 'parent') properties/methods directly into the thread code. That's all.


Concerning your last remark, do you mean "Lazarus" 1.0.8 ?

Which sounds a bit strange to me, because  I guess EventLog is most probably a part of FPC, not of Lazarus. Unless Code Typhoon is also using a newer version of FPC (I know there are still a few bug issues with the next-to-come FPC 2.7.1. release).

mdalacu

  • Full Member
  • ***
  • Posts: 233
    • dmSimpleApps
Re: Getting started with a service (LazDaemon)
« Reply #21 on: June 10, 2013, 08:08:07 am »
Of course, your code works perfectly! Thank you again ChrisF.
My program was exactly like yours except the line where i was calling the logger:
Code: [Select]
Daemon1.EventLog1.Info('Tick.'); 
By change it into Parent.EventLog1.Info('Tick.');   , everything works. So, i still does not understand the differences...Demon1 is the parent of my TWorkingThread, but if i call it this way it crashes.  :o

For the second issue, yes i was referring to the shipped with CT 4.30. And yes it is using a newer fpc 2.7.1, but if i use eventlog.pp from 1.0.8 then it works in CT 4.30, so i don't think it is related with fpc 2.7.1.
All i have to do now is to get rid of the "ugly text" inserted into the System Log (http://bugs.freepascal.org/view.php?id=24390), which i still don't figure how to do it.

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Getting started with a service (LazDaemon)
« Reply #22 on: June 10, 2013, 02:23:36 pm »
I've also noticed that the messages in the windows system log are not correctly formatted.

According to the infos posted into the bug issue you've reported, and after a few tests, adding the 'fclel.res' file did the trick for me.

Attached, a modified version of my last sample with this solution. You must use only the EvenLog.Warning, .Error, .Debug and .Info methods to obtain valid and formated messages (and not use the EventLog.Log method, which is undefined into the fclel.res file).

Just for test purposes, I've used all the 4 possibilities into this last sample, as you can see.

Note: the messages are correctly formatted, but only if the concerned service is installed. If not, you'll still get unformatted message displays. It's not necessary that the service is running; but it must be installed (to let windows access to the concerned formatting infos).

Another possibility seems to build your own message format file, and to register it with the EventLog.RegisterMessageFile method; I've not tried it, but according to the bug issue, it's also working.

mdalacu

  • Full Member
  • ***
  • Posts: 233
    • dmSimpleApps
Re: Getting started with a service (LazDaemon)
« Reply #23 on: June 11, 2013, 07:43:44 am »
Thank you, it works. Now all my previous log entries are correctly formatted!  :o  :D
This forum needs a achievements system or a thank you button for posts like yours!

mdalacu

  • Full Member
  • ***
  • Posts: 233
    • dmSimpleApps
Re: Getting started with a service (LazDaemon)
« Reply #24 on: December 11, 2015, 11:02:24 am »
I have another BIG problem....

I have started to create a daemon which has a main thread, windows platform.
This main thread spanws other work threads. This work threads has OnTerminate  property filled with a procedure from the main thread.
The problem is that these work threads, when they terminate, never calls this HandleTerminatedThreads procedure.
The problem is that demon applications do not have an event loop?
What can i do....help %)

Thank you.

mglazuser

  • Newbie
  • Posts: 2
Re: Getting started with a service (LazDaemon)
« Reply #25 on: November 30, 2016, 08:49:53 pm »
Same issue #25. Thread.OnTerminate is not working, the assigned procedure is never been called after Thread.Terminate. Any suggestions to this problem?
Thx in advance.
« Last Edit: December 01, 2016, 04:45:50 pm by mglazuser »

mglazuser

  • Newbie
  • Posts: 2
Re: Getting started with a service (LazDaemon)
« Reply #26 on: December 01, 2016, 03:14:43 pm »
In my opininon its a bug of FPC with the title "Thread destructor not called in daemons". That refers to Windows 7

The Event OnTerminate(@ThreadStopped) will never be called, its useless to implement it, you can check this also in the example of ChrisF #15 above.
..
procedure TTestDaemon.ThreadStopped(Sender: TObject); // never been called!
begin
  FreeAndNil(FThread); //USELESS :-(
end;
..

As a workaround you have to handle the problem manually and call the destructor of your thread by yourself as ChrisF suggested in #22 with a Event. Or you use FreeOnTerminate=True like here http://www.gocher.me/Daemon
« Last Edit: December 02, 2016, 03:25:32 pm by mglazuser »

ngx234

  • New Member
  • *
  • Posts: 10
Re: Getting started with a service (LazDaemon)
« Reply #27 on: January 10, 2022, 06:37:31 am »
This one -> OK

Only one bug, mem leak when stop the service

Code: Pascal  [Select][+][-]
  1. { Lazarus servie, Windows 10 64.
  2.   Lazarus 2.2.0 (rev lazarus_2_2_0-7-gb938b1d561)
  3.   FPC 3.2.3 i386-win32-win32/win64
  4.  
  5. Windows: cmd line administrator:
  6.   install service  : LazarusService.exe -i
  7.                    : sc create "LazarusService" binpath="C:\L\_src\DaemonService\Service\LazarusService.exe"
  8.   start service    : sc start LazarusService
  9.   stop service     : sc stop LazarusService --> mem leak
  10.   uninstall service: sc delete LazarusService
  11.   check status     : sc queryex LazarusService
  12.  
  13. https://forum.lazarus.freepascal.org/index.php/topic,57754.0.html, thanks getmem }
  14.  
  15. program LazarusService;
  16.  
  17. {$mode objfpc}{$H+}
  18.  
  19. uses
  20.   HeapTrc,
  21. {$IFDEF UNIX}{$IFDEF UseCThreads}
  22.   CThreads,
  23. {$ENDIF} Cmem,{$ENDIF}
  24.   sysutils, classes, daemonapp, {jwawindows, } eventlog;
  25.  
  26. type
  27.  
  28.   { TWorkerThread }
  29.   TWorkerThread = class(TThread)
  30.   private
  31.     FIsPaused: Boolean;
  32.   protected
  33.     procedure Execute; override;
  34.   public
  35.     destructor Destroy; override;
  36.   end;
  37.  
  38.   TDaemon = class(TCustomDaemon)
  39.   private
  40.     FWorkerThread: TWorkerThread;
  41.     procedure DoTerminate(Sender: TObject);
  42.   public
  43.     function ShutDown: Boolean; override;
  44.     function Stop: Boolean; override;
  45.     function Start: Boolean; override;
  46.     function Pause: Boolean; override;
  47.     function Continue: Boolean; override;
  48.   end;
  49.  
  50.   TDaemonMapper = class(TCustomDaemonMapper)
  51.   private
  52.   public
  53.     constructor Create(AOwner: TComponent); override;
  54.   end;
  55.  
  56. procedure TWorkerThread.Execute;
  57. const ii : int64 = 0;
  58. begin
  59.   Application.Log(etDebug, 'WorkerThreadExecute: entering Execute event');
  60.   try
  61.     while not Terminated do begin
  62.       try
  63.         Sleep(5000);
  64.         if (not FIsPaused) then begin
  65.           //do something
  66.         end;
  67.         Application.Log(etDebug, ii.ToString);
  68.         inc(ii);
  69.       except
  70.         on e:Exception do begin
  71.           Application.Log(etDebug, e.Message);
  72.         end;//on e
  73.       end;//except
  74.     end;//while
  75.   finally
  76.     Application.Log(etDebug, 'WorkerThreadExecute: leaving Execute event ---- .');
  77.     OnTerminate(Self);
  78.   end;
  79. end;//procedure TWorkerThread.Execute;
  80.  
  81. destructor TWorkerThread.Destroy;
  82. begin
  83.   Application.Log(etDebug, 'WorkerThreadDestroy');
  84.   inherited Destroy;
  85. end;
  86.  
  87. procedure TDaemon.DoTerminate(Sender: TObject);
  88. begin
  89.   Application.Log(etDebug, 'DaemonDoTerminate: Worker thread terminated!!!!!');
  90.   if FWorkerThread <> nil then
  91.     FreeAndNil(FWorkerThread);
  92. end;
  93.  
  94. function TDaemon.Start: Boolean;
  95. begin
  96.   Result := inherited Start;
  97.   Application.Log(etDebug, 'DaemonStart: LazarusService started.');
  98.   FWorkerThread := TWorkerThread.Create(True);
  99.   FWorkerThread.FIsPaused := False;
  100.   FWorkerThread.OnTerminate := @DoTerminate;
  101.   FWorkerThread.FreeOnTerminate := False;
  102.   FWorkerThread.Start;
  103. end;
  104.  
  105. function TDaemon.Stop: Boolean;
  106. var ii : Int64 = 0;
  107. begin
  108.   FWorkerThread.Terminate;
  109.   while(FWorkerThread<>nil)do begin
  110.     Sleep(500);
  111.     Application.Log(etDebug, 'DaemonStop: Waiting for workerThread '+ii.ToString);
  112.     inc(ii);
  113.   end;
  114.   Result := inherited Stop;
  115.   Application.Log(etDebug, 'DaemonStop: LazarusService stopped.');
  116. end;
  117.  
  118. function TDaemon.Pause: Boolean;
  119. begin
  120.   Result := inherited Pause;
  121.   FWorkerThread.FIsPaused := True;
  122.   Application.Log(etDebug, 'DaemonPause: LazarusService paused.');
  123. end;
  124.  
  125. function TDaemon.Continue: Boolean;
  126. begin
  127.   Result := inherited Continue;
  128.   FWorkerThread.FIsPaused := False;
  129.   Application.Log(etDebug, 'DaemonContinue: LazarusService resumed.');
  130. end;
  131.  
  132. function TDaemon.ShutDown: Boolean;
  133. begin
  134.   Result := inherited ShutDown;
  135.   Application.Log(etDebug, 'DaemonShutdown: LazarusService shutdown.');
  136. end;
  137.  
  138. constructor TDaemonMapper.Create(AOwner: TComponent);
  139. var MyDaemonDef: TDaemonDef;
  140. begin
  141.   inherited Create(AOwner);
  142.   Application.Log(etDebug, 'DaemonCreate: LazarusService successfully created.');
  143.   MyDaemonDef := DaemonDefs.Add as TDaemonDef;
  144.   MyDaemonDef.DaemonClassName := TDaemon.ClassName;
  145.   MyDaemonDef.Name := 'LazarusService';
  146.   MyDaemonDef.DisplayName := 'LazarusService display name';
  147.   MyDaemonDef.Description := 'Description Break session 0 isolation';
  148.   MyDaemonDef.LogStatusReport := False;
  149.   with MyDaemonDef.WinBindings do begin
  150.     ServiceType := stWin32;
  151.     StartType := stAuto; //stBoot //stManual
  152.     ErrorSeverity := esNormal;
  153.     WaitHint := 0;
  154.     IDTag := 0;
  155.   end;
  156. end;//constructor TDaemonMapper.Create(AOwner: TComponent);
  157.  
  158. begin//main program LazarusService;
  159.   RegisterDaemonClass(TDaemon);
  160.   RegisterDaemonMapper(TDaemonMapper);
  161.   heaptrc.SetHeapTraceOutput(ChangeFileExt(ParamStr(0), '.heaptrc.txt'));
  162.   with Application do begin
  163.     Title := 'LazarusServiceApplication';
  164.     EventLog.LogType := ltFile;
  165.     EventLog.DefaultEventType := etDebug;
  166.     EventLog.AppendContent := true;
  167.     //EventLog.FileName := ExtractFilePath(Application.ExeName) + '.log';
  168.     EventLog.FileName := ChangeFileExt(ParamStr(0), '.log');
  169.     Initialize;
  170.     Run;
  171.   end;
  172. end.//file  




C:\L\_src\DaemonService\Service>LazarusService.exe -i

C:\L\_src\DaemonService\Service>dir
 Volume in drive C is ssd111
 Volume Serial Number is F4F2-65F4

 Directory of C:\L\_src\DaemonService\Service

01/10/2022  12:22    <DIR>          .
01/10/2022  12:22    <DIR>          ..
01/10/2022  12:15    <DIR>          backup
01/10/2022  11:46           263,680 LazarusService.exe
01/10/2022  12:22               327 LazarusService.heaptrc.txt
01/10/2022  12:22                99 LazarusService.log
01/10/2022  11:46             1,973 LazarusService.lpi
01/10/2022  12:15            10,702 LazarusService.lpr
01/07/2022  16:04            23,277 LazarusService.lpr.html
01/10/2022  11:46            10,457 LazarusService.lps
01/07/2022  16:51            17,935 LazarusService__OK.lpr
01/10/2022  11:27    <DIR>          lib
               8 File(s)        328,450 bytes
               4 Dir(s)  75,417,079,808 bytes free

C:\L\_src\DaemonService\Service>type LazarusService.log
LazarusService [2022-01-10 12:22:21.310 Debug] DaemonCreate: LazarusService successfully created.

C:\L\_src\DaemonService\Service>type LazarusService.heaptrc.txt
C:\L\_src\DaemonService\Service\LazarusService.exe -i
Heap dump by heaptrc unit of C:\L\_src\DaemonService\Service\LazarusService.exe
171 memory blocks allocated : 5941/6368
171 memory blocks freed     : 5941/6368
0 unfreed memory blocks : 0
True heap size : 262144 (128 used in System startup)
True free heap : 262016

C:\L\_src\DaemonService\Service>sc queryex lazarusService

SERVICE_NAME: lazarusService
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 1  STOPPED
        WIN32_EXIT_CODE    : 1077  (0x435)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 0
        FLAGS              :

C:\L\_src\DaemonService\Service>sc start lazarusService

SERVICE_NAME: lazarusService
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 9852
        FLAGS              :

C:\L\_src\DaemonService\Service>type LazarusService.log
LazarusService [2022-01-10 12:22:21.310 Debug] DaemonCreate: LazarusService successfully created.
LazarusService [2022-01-10 12:23:10.956 Debug] DaemonCreate: LazarusService successfully created.
LazarusService [2022-01-10 12:23:10.958 Debug] DaemonStart: LazarusService started.
LazarusService [2022-01-10 12:23:10.958 Debug] WorkerThreadExecute: entering Execute event
LazarusService [2022-01-10 12:23:15.960 Debug] 0
LazarusService [2022-01-10 12:23:20.966 Debug] 1

C:\L\_src\DaemonService\Service>type LazarusService.heaptrc.txt
C:\L\_src\DaemonService\Service\LazarusService.exe -i
Heap dump by heaptrc unit of C:\L\_src\DaemonService\Service\LazarusService.exe
171 memory blocks allocated : 5941/6368
171 memory blocks freed     : 5941/6368
0 unfreed memory blocks : 0
True heap size : 262144 (128 used in System startup)
True free heap : 262016

C:\L\_src\DaemonService\Service>sc stop lazarusService

SERVICE_NAME: lazarusService
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 3  STOP_PENDING
                                (STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

C:\L\_src\DaemonService\Service>sc queryex lazarusService

SERVICE_NAME: lazarusService
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 1  STOPPED
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 0
        FLAGS              :

C:\L\_src\DaemonService\Service>type LazarusService.log
LazarusService [2022-01-10 12:22:21.310 Debug] DaemonCreate: LazarusService successfully created. --> LazarusService.exe -i
LazarusService [2022-01-10 12:23:10.956 Debug] DaemonCreate: LazarusService successfully created. --> sc start lazarusService (why twice?)
LazarusService [2022-01-10 12:23:10.958 Debug] DaemonStart: LazarusService started.
LazarusService [2022-01-10 12:23:10.958 Debug] WorkerThreadExecute: entering Execute event
LazarusService [2022-01-10 12:23:15.960 Debug] 0
LazarusService [2022-01-10 12:23:20.966 Debug] 1
LazarusService [2022-01-10 12:23:25.981 Debug] 2
LazarusService [2022-01-10 12:23:30.995 Debug] 3
LazarusService [2022-01-10 12:23:36.008 Debug] 4
LazarusService [2022-01-10 12:23:41.019 Debug] 5
LazarusService [2022-01-10 12:23:46.024 Debug] 6
LazarusService [2022-01-10 12:23:48.315 Debug] DaemonStop: Waiting for workerThread 0
LazarusService [2022-01-10 12:23:48.829 Debug] DaemonStop: Waiting for workerThread 1
LazarusService [2022-01-10 12:23:49.343 Debug] DaemonStop: Waiting for workerThread 2
LazarusService [2022-01-10 12:23:49.844 Debug] DaemonStop: Waiting for workerThread 3
LazarusService [2022-01-10 12:23:50.357 Debug] DaemonStop: Waiting for workerThread 4
LazarusService [2022-01-10 12:23:50.858 Debug] DaemonStop: Waiting for workerThread 5
LazarusService [2022-01-10 12:23:51.031 Debug] 7
LazarusService [2022-01-10 12:23:51.031 Debug] WorkerThreadExecute: leaving Execute event ---- .
LazarusService [2022-01-10 12:23:51.031 Debug] DaemonDoTerminate: Worker thread terminated!!!!!
LazarusService [2022-01-10 12:23:51.031 Debug] WorkerThreadDestroy
LazarusService [2022-01-10 12:23:51.373 Debug] DaemonStop: Waiting for workerThread 6
LazarusService [2022-01-10 12:23:51.373 Debug] DaemonStop: LazarusService stopped.

C:\L\_src\DaemonService\Service>type LazarusService.heaptrc.txt
C:\L\_src\DaemonService\Service\LazarusService.exe -i
Heap dump by heaptrc unit of C:\L\_src\DaemonService\Service\LazarusService.exe
171 memory blocks allocated : 5941/6368
171 memory blocks freed     : 5941/6368
0 unfreed memory blocks : 0
True heap size : 262144 (128 used in System startup)
True free heap : 262016
C:\L\_src\DaemonService\Service\LazarusService.exe --run
Heap dump by heaptrc unit of C:\L\_src\DaemonService\Service\LazarusService.exe
320 memory blocks allocated : 12509/13576
319 memory blocks freed     : 12457/13520
1 unfreed memory blocks : 52                            -->> sc stop -> mem leak
True heap size : 262144 (128 used in System startup)
True free heap : 262016
Should be : 261864
Call trace for block $01564B38 size 52
  $00401BB1
  $0042E821
  $0040330F
  $75F5FA29
  $779C7A9E
  $779C7A6E
  $0042E821
  $0040330F
  $75F5FA29
  $779C7A9E
  $779C7A6E

C:\L\_src\DaemonService\Service>sc delete LazarusService
[SC] DeleteService SUCCESS

C:\L\_src\DaemonService\Service>   




balazsszekely

  • Guest
Re: Getting started with a service (LazDaemon)
« Reply #28 on: January 10, 2022, 08:51:33 am »
@ngx234

Quote
Only one bug, mem leak when stop the service
Hope you are not a spammer.

Code: Pascal  [Select][+][-]
  1. function TDaemon.Stop: Boolean;
  2. var ii : Int64 = 0;
  3. begin
  4.   FWorkerThread.Terminate;
  5.   FWorkerThread.WaitFor; //<--add this
  6.   FWorkerThread.Free;//<--add this
  7.   while(FWorkerThread<>nil)do begin
  8.     Sleep(500);
  9.     Application.Log(etDebug, 'DaemonStop: Waiting for workerThread '+ii.ToString);
  10.     inc(ii);
  11.   end;
  12.   Result := inherited Stop;
  13.   Application.Log(etDebug, 'DaemonStop: LazarusService stopped.');
  14. end;

ngx234

  • New Member
  • *
  • Posts: 10
Re: Getting started with a service (LazDaemon)
« Reply #29 on: January 10, 2022, 10:53:22 am »
@getmem, no more memory leak,

but the service can not be stopped. Always in STATE=3 STOP_PENDING

Tried on Win10 x64, Win7 x86, win7 x64

Code: Pascal  [Select][+][-]
  1. function TDaemon.Stop: Boolean;
  2. var ii : Int64 = 0;
  3. begin
  4.   FWorkerThread.Terminate;
  5.   Application.Log(etDebug, 'DaemonStop: After terminate');
  6.   FWorkerThread.WaitFor;
  7.   Application.Log(etDebug, 'DaemonStop: After waitfor');  //doesn't come here ......
  8.   FWorkerThread.Free;
  9.   Application.Log(etDebug, 'DaemonStop: After free');
  10.   while(FWorkerThread<>nil)do begin
  11.     Sleep(500);
  12.     Application.Log(etDebug, 'DaemonStop: Waiting for workerThread '+ii.ToString);
  13.     inc(ii);
  14.   end;
  15.   Result := inherited Stop;
  16.   Application.Log(etDebug, 'DaemonStop: LazarusService stopped.');
  17. end;

C:\L\w7x64>LazarusService.exe -i

C:\L\w7x64>type LazarusService.heaptrc.txt
C:\L\w7x64\LazarusService.exe -i
Heap dump by heaptrc unit of C:\L\w7x64\LazarusService.exe
171 memory blocks allocated : 5566/6008
171 memory blocks freed     : 5566/6008
0 unfreed memory blocks : 0
True heap size : 229376 (112 used in System startup)
True free heap : 229264

C:\L\w7x64>type LazarusService.log
LazarusService [2022-01-10 16:46:55.284 Debug] DaemonCreate: LazarusService successfully created.

C:\L\w7x64>sc start LazarusService

SERVICE_NAME: LazarusService
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x7d0
        PID                : 2420
        FLAGS              :

C:\L\w7x64>sc queryex LazarusService

SERVICE_NAME: LazarusService
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 4  RUNNING
                                (STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 2420
        FLAGS              :

C:\L\w7x64>type LazarusService.log
LazarusService [2022-01-10 16:46:55.284 Debug] DaemonCreate: LazarusService successfully created.
LazarusService [2022-01-10 16:47:41.866 Debug] DaemonCreate: LazarusService successfully created.
LazarusService [2022-01-10 16:47:41.866 Debug] DaemonStart: LazarusService started.
LazarusService [2022-01-10 16:47:41.881 Debug] WorkerThreadExecute: entering Execute event
LazarusService [2022-01-10 16:47:46.889 Debug] 0
LazarusService [2022-01-10 16:47:51.897 Debug] 1
LazarusService [2022-01-10 16:47:56.904 Debug] 2

C:\L\w7x64>type LazarusService.heaptrc.txt
C:\L\w7x64\LazarusService.exe -i
Heap dump by heaptrc unit of C:\L\w7x64\LazarusService.exe
171 memory blocks allocated : 5566/6008
171 memory blocks freed     : 5566/6008
0 unfreed memory blocks : 0
True heap size : 229376 (112 used in System startup)
True free heap : 229264

C:\L\w7x64>sc stop LazarusService

SERVICE_NAME: LazarusService
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 3  STOP_PENDING
                                (STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

C:\L\w7x64>type LazarusService.heaptrc.txt
C:\L\w7x64\LazarusService.exe -i
Heap dump by heaptrc unit of C:\L\w7x64\LazarusService.exe
171 memory blocks allocated : 5566/6008
171 memory blocks freed     : 5566/6008
0 unfreed memory blocks : 0
True heap size : 229376 (112 used in System startup)
True free heap : 229264

C:\L\w7x64>type LazarusService.log
LazarusService [2022-01-10 16:46:55.284 Debug] DaemonCreate: LazarusService successfully created.
LazarusService [2022-01-10 16:47:41.866 Debug] DaemonCreate: LazarusService successfully created.
LazarusService [2022-01-10 16:47:41.866 Debug] DaemonStart: LazarusService started.
LazarusService [2022-01-10 16:47:41.881 Debug] WorkerThreadExecute: entering Execute event
LazarusService [2022-01-10 16:47:46.889 Debug] 0
LazarusService [2022-01-10 16:47:51.897 Debug] 1
LazarusService [2022-01-10 16:47:56.904 Debug] 2
LazarusService [2022-01-10 16:48:01.912 Debug] 3
LazarusService [2022-01-10 16:48:06.919 Debug] 4
LazarusService [2022-01-10 16:48:11.927 Debug] 5
LazarusService [2022-01-10 16:48:16.935 Debug] 6
LazarusService [2022-01-10 16:48:21.942 Debug] 7
LazarusService [2022-01-10 16:48:22.831 Debug] DaemonStop: After terminate
LazarusService [2022-01-10 16:48:26.950 Debug] 8
LazarusService [2022-01-10 16:48:26.950 Debug] WorkerThreadExecute: leaving Execute event ---- .
LazarusService [2022-01-10 16:48:26.950 Debug] DaemonDoTerminate: Worker thread terminated!!!!!
LazarusService [2022-01-10 16:48:26.950 Debug] WorkerThreadDestroy

C:\L\w7x64>sc queryex LazarusService

SERVICE_NAME: LazarusService
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 3  STOP_PENDING
                                (STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 2420
        FLAGS              :

C:\L\w7x64>sc queryex LazarusService

SERVICE_NAME: LazarusService
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 3  STOP_PENDING
                                (STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 2420
        FLAGS              :

C:\L\w7x64>sc stop LazarusService
[SC] ControlService FAILED 1061:

The service cannot accept control messages at this time.


C:\L\w7x64>





 

TinyPortal © 2005-2018