lamberms has asked for the wisdom of the Perl Monks concerning the following question:

Hello All, I just wrote my first Windows service using ActiveState's PerlSvc PDK tool. I have gotten the service starting correctly. However, every time I go to shut it down it dies with a Microsoft Management Console error of 1067 - The process terminated unexpectedly. Does anyone have any ideas of what may be causing this?
Thanks in advance,
Mike

Replies are listed 'Best First'.
Re: PerlSvc Ends With Error 1067
by arden (Curate) on Mar 02, 2004 at 23:33 UTC
    lamberms, a bit more information please.
    • What version of the Perl Developer Kit are you using? If not 5.3.0.530, upgrade (it's free) and see if it's one of the features fixed.
    • What version of perl are you using (5.6.1 or 5.8)?
    • What version of Windows are you using (NT, 2000, 2003, XP)?
    • If you run your app in interactive mode, does it have any problems exitting?
    • Finally, how about showing us your code, or at least the parts of it that should be relevant? Specifically, the functions:
      sub Startup {} sub Continue {}

    - - arden.

    oh yeah, how long does it take to stop if you type net stop servicename at the command prompt?

      Arden, Thanks for the reply. Here is my startup code:

      sub Startup { report("Info: $Config{ServiceName} Starting"); Initialize(); while (ContinueRun()) { # EVENT LOOP if ($shared_memory_server) { # Maintain Worker Threads $shared_memory_server->service_worker_procs(); # Service Unique Id Requests $shared_memory_server->service_unique_id_requests(); # Reap Old Results Out Of The System if (sleptfor("reap_old_results",10)) { $shared_memory_server->reap_old_results(); } if (sleptfor("reload_config",60)) { if ((-M "$base_dir\\Mail_Daemon.conf") < $config_file_ +modify_info) { $config_file_modify_info = (-M "$base_dir\\Mail_Da +emon.conf"); report("Info: $Config{ServiceName} Configuration U +pdated ... Reloading"); $shared_memory_server->reload_configuration(); } } if (sleptfor("read_status",5)) { if ($shared_memory_server->read_directive() eq "DIE") +{ $shared_memory_server->set_directive("DIE_PROCS"); # Need To Wait For All Processes To Die Before Dyi +ng Myself report("Info: $Config{ServiceName} Killing Myself +... Waiting For Workers To Die"); $proc_kill_timeout = time + 30; while (not $shared_memory_server->no_workers_left( +)) { # Put check in here ... if the procs are not d +ead with 30 seconds # kill forcefully Win32::Sleep(500); if (time > $proc_kill_timeout) { report("Info: $Config{ServiceName} Process +es Hung ... Hard Killing Processes"); $shared_memory_server->DESTROY(-1); } } report("Info: $Config{ServiceName} All Processes D +ead. Exiting"); exit; } } Win32::Sleep(100); } } # Report how long the service is going to take to close PerlSvc::ReportStatus(PerlSvc::SERVICE_STOP_PENDING(), 35); report("Info: $Config{ServiceName} Stop Request Granted ... Waitin +g For Workers To Die"); $shared_memory_server->set_directive("DIE_PROCS"); $proc_kill_timeout = time + 30; while (not $shared_memory_server->no_workers_left()) { # Put check in here ... if the procs are not dead with 30 seco +nds # kill forcefully Win32::Sleep(500); if (time > $proc_kill_timeout) { report("Info: $Config{ServiceName} Processes Hung ... Hard + Killing Processes."); $shared_memory_server->DESTROY(-1); } } report("Info: $Config{ServiceName} Stopping"); exit; }


      Basically, my service launches a bunch of subprocesses that communicate via a shared memory dll I wrote. When the ContinueRun function returns false my the DIE_PROCS communication tells those processes to die. They do die successfully. The server even dies (I see the $Config{ServiceName} Stopping message in the event logs. When it dies however I get the error. I thought the PerlSvc::ReportStatus command told the service manager how long to expect to wait for the service to end.
      I am using version 5.6.1 of Perl and the newest version of the PDK. I have tried this in Windows 2000 and XP with the same result. I have run it in interactive and non-interactive mode with the same result. It takes about 10 seconds to stop the service.
      Best Regards
      Mike
Re: PerlSvc Ends With Error 1067
by flyingmoose (Priest) on Mar 03, 2004 at 01:43 UTC
    The process terminated unexpectedly

    I can't speak from Perl experience (not having written any Win32 perl services), but from maintaining a C++/Java service our company has, I can say a few things about "Unexpected Shutdown". I've chased these kind of defects for weeks! The service must end in 3 seconds after recieving the request to shut down. If you ignore the request or are too slow, you'll see this message. Look at your active state docs and see if you are handling that shutdown hook decently...decent threading should help you somewhat, but make sure all of your threads will end nicely when requested!

      You can also delay the shutdown in your main thread by requestin more shutdown time from the service manager... Win32::Daemon has a function for this.. so I would imagin PDK does as well. Something like
      my $active_children = 1; while(1) { if($SERVICE_STATE eq "SHUTTING_DOWN") { if($active_children) { requestMoreTime(x); ShutDownChildren(\$active_children); } last if !$active_children; } sleep(x); }
      Just a very high level idea of how you might pull this off... Its very pseudo code and it could be horrible.. but hopefully its on the right track

      Grygonos
Re: PerlSvc Ends With Error 1067
by lamberms (Sexton) on Mar 03, 2004 at 16:38 UTC
    Hey everyone, By adding the following code just before the last exit (see above code) I was able to not get this error:

    PerlSvc::ReportStatus(PerlSvc::SERVICE_STOPPED());


    Thanks for all your suggestions. I appreciate the help you gave.
    Best Regards,
    Mike