win32 service and time.sleep()

Laszlo Zsolt Nagy gandalf at designaproduct.biz
Tue Sep 20 11:07:08 EDT 2005


rbt wrote:

>I have a win32 service written in Python. It works well. It sends a
>report of the status of the machine via email periodically. The one
>problem I have is this... while trying to send an email, the script
>loops until a send happens and then it breaks. Should it be unable to
>send, it sleeps for 10 minutes with time.sleep(600) and then wakes and
>tries again. This is when the problem occurs. I can't stop the service
>while the program is sleeping. When I try, it just hangs until a reboot.
>Can some suggest how to fix this?
>  
>
Yes. Generally, most of the win32 services work like this:

- the main thread listens to win32 service commands
- when starting the service, you should create a new worker thread that 
does the job for you
- when stopping the service, your service should report 
win32service.SERVICE_STOP_PENDING immediately, and ask the worker thread 
to terminate
- you should be continuously reporting win32service.SERVICE_STOP_PENDING 
until your workder thread has stopped

Here is a simple module that uses a 'Processor' class and a new thread 
to do the work.
(The full program is here: http://mess.hu/download/SimpleHTTPService.zip )

class Service(win32serviceutil.ServiceFramework):
    _svc_name_ = SERVICE_NAME
    _svc_display_name_ = SERVICE_DISPLAY
    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.stopped = threading.Event()
        self.stopped.clear()
        self.logger = getLogger(SERVICE_NAME)

    def SvcStop(self):
        self.logger.info("Got SvcStop, trying to stop service...")
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        self.stopped.set()

    def SvcDoRun(self):
        """Write an event log record - in debug mode we will also see 
this message printed."""
        try:
            import servicemanager
            servicemanager.LogMsg(
                    servicemanager.EVENTLOG_INFORMATION_TYPE,
                    servicemanager.PYS_SERVICE_STARTED,
                    (self._svc_name_, '')
                    )
            self.logger.info("Started.")
            self.logger.debug("Creating processor instance")
            processor = Processor(self.stopped)
            self.logger.debug("Starting processor thread")
            thread.start_new_thread(processor.Process,())
            self.logger.debug("Waiting for the processor thread to finish")
            self.stopped.wait()
            self.logger.debug("Stopping")
            time.sleep(1)
            while not processor.stopped.isSet():
                
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING, 5000)
                time.sleep(5)
            servicemanager.LogMsg(
                    servicemanager.EVENTLOG_INFORMATION_TYPE,
                    servicemanager.PYS_SERVICE_STOPPED,
                    (self._svc_name_, "")
                    )
            self.logger.info("Stopped")
        except:
            self.logger.error('',exc_info = sys.exc_info())


if __name__=='__main__':
    win32serviceutil.HandleCommandLine(Service)



More information about the Python-list mailing list