This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Cygwin service doesn't get NT shutdown notification


I'm trying to write a wrapper for the Cygwin port of PostgreSQL so
that it can run as an NT service and stop cleanly when the service is
stopped or shutdown due to system shutdown.  I've got it working well
when the service is stopped manually, but when I shutdown/restart my
NT system the service process seems to get killed without being
notified of the shutdown.

I've written a simple NT service that can be built for both Cygwin and
native NT (based on code from Corinna Vinschen, Chuck Wilson, and
Jason Tishler).  The native Win32 version *does* catch and handle the
shutdown event, but the same code built for Cygwin does not seem to
get the event.

I'm very interested in solving this problem so that the Cygwin version
too can catch and handle the shutdown event.  Can anyone suggest some
way to attack the problem?  Is there some way to trace what's going on
that might shed some light?  Unfortunately, much of the action is
internal to the Windows NT mechanism for communicating from the
Service Control Manager to the supervisory thread in the service
process itself, all of which is opague.  In particular, I don't know
what form of IPC is used to signal the shutdown event.  It's
interesting that the Cygwin service process does catch and handle the
event for a manual stop of the service.

Does something happen during NT shutdown that disables or kills all
running Cygwin processes, that might kill a service process before it
gets the SHUTDOWN notification?  Does something happen to/within the
shared Cygwin DLL at shutdown?  Will calls to functions provided by
the Cygwin DLL fail during shutdown? 

The source code I'm using for this test is available at
<http://ontosys.com/src/testcygservice.tgz>.  I would be most grateful
for any help in inspecting the code and testing the execution.  I've
attached a copy of commentary from the code that explains how to build
and run it.

-- 
Fred Yankowski           fred@OntoSys.com      tel: +1.630.879.1312
Principal Consultant     www.OntoSys.com       fax: +1.630.879.1370
OntoSys, Inc             38W242 Deerpath Rd, Batavia, IL 60510, USA

--

This file provides all the code needed to create a simple NT service,
including command-line functions to install and remove the service.
The service itself simply prints a status message every few seconds to
a logfile.

This code can be built using Cygwin/gcc, or using MS VC++ for a
native/non-Cygwin build.  The point is to track down a problem where
NT services built with Cygwin don't get a chance to shutdown cleanly
when the system is shutdown.

To build for Cygwin, simply run 'make'.

To build using VC++, create a new 'Win32 Application' project.  Add
service.c to the project.  In the Link/Output settings, set the
entry-point symbol to 'mainCRTStartup' (no quotes, of course).  Build
as normal.

To install the service, do the following from a shell:

   $ ./service.exe --install-as-service

That creates a service named testcygservice or testwinservice for the
Cygwin or non-Cygwin build, respectively.  Look in the generated
testcygservice.log (or testwinservice.log) file to check for any error
reports.

To run the service, just do

   $ net start testcygservice   # or testwinservice

When run as a service the log file will be created in the
$SYSTEMROOT/system32 folder.

To test operation over a restart, start the service as above, verify
that it's operating by checking that the log file is getting new
"count = NN" messages every few seconds, then restart the system.

Check the logfile again after the restart finishes.  If the service
was able to catch the shutdown event the logfile will contain messages
like this:

If the service does catch the shutdown event then the logfile will
include a section like this:

	13:32:39 count = 26
	13:32:44 count = 27
	13:32:48 service_handler(5) begins
	13:32:49 count = 28
	13:32:49 work_main() ends
	13:32:49 work process stopping
	13:35:40 service_main(1,) begins
	13:35:40 work_main() begins
	13:35:45 count = 0
	13:35:50 count = 1

The "service_handler(5)" message shows it catching the SHUTDOWN
notification from the NT Service Control Manager, and then doing a
clean shutdown.

If the service *doesn't* catch the shutdown event the logfile will
have a section like this, where the "service_main" message is the
first message logged after restart:

      14:06:14 count = 19
      14:06:19 count = 20
      14:09:08 service_main(1,) begins
      14:09:08 work_main() begins
      14:09:13 count = 0
      14:09:18 count = 1

To uninstall the service, do

   $ net stop testcygservice
   $ ./service.exe --remove-as-service


--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]