Hi (ex Dave) support,

May I offer a suggestion for improvement to the Win32::Daemon service code 
sample contained under the following URL, mainly concentrating on "Example 5" 
Using different callback routines
http://search.cpan.org/~jdb/Win32-Daemon-20110117/Daemon.pm

The sample code appeared to fail to recover from the Windows Service state 
transitions from the Pause to Resume service state. It appears that further 
state tests and transitions are required to get the perl state process to be in 
agreement with Windows requirements of continue-pending before resuming and to 
get the Perl service back running.
The changes for your consideration are in the Callback_Running and 
Callback_Continue subroutines and would also be applicable for the test sample 
code snippets contained in the Win32-Daemon-20110117.tar.gz off the URL.

Testing environment: Perl5.10 & Perl5.14, Win32|XP & Win32|Winserver2003

Please, I would appreciate not having my email address published.

Regards,
Peter Stevens,
Melbourne Australia

**************************************************************
This email, including all attachments, is confidential and for the sole use of
the intended recipient(s).  If you are not the intended recipient, you are
prohibited from disclosing, distributing, or in any other way using it.
If you have received this email in error, please notify me by return email, 
or contact the AEMO Helpdesk on 1300 300 295, and then delete this email. 
**************************************************************
    use Win32::Daemon;
    Win32::Daemon::RegisterCallbacks( {
        start       =>  \&Callback_Start,
        running     =>  \&Callback_Running,
        stop        =>  \&Callback_Stop,
        pause       =>  \&Callback_Pause,
        continue    =>  \&Callback_Continue,
    } );

    %Context = (
        last_state => SERVICE_STOPPED,
        start_time => time(),
    );
    
    # Start the service passing in a context and
    # indicating to callback using the "Running" event
    # every 2000 milliseconds (2 seconds).
    Win32::Daemon::StartService( \%Context, 2000 );
    
    sub Callback_Running
    {
        my( $Event, $Context ) = @_;
        
        # Note that here you want to check that the state
        # is indeed SERVICE_RUNNING. Even though the Running
        # callback is called it could have done so before 
        # calling the "Start" callback.
        if( SERVICE_RUNNING == Win32::Daemon::State() )
        {
            # ... process your main stuff here...
            # ... note that here there is no need to
            #     change the state
        }
                elsif (SERVICE_PENDING_CONTINUE == Win32::Daemon::State() )
                {
                        Win32::Daemon::State( SERVICE_RUNNING );
                }
                else
                {
                }

    sub Callback_Start
    {
        my( $Event, $Context ) = @_;
        # Initialization code
        # ...do whatever you need to do to start...

        $Context->{last_state} = SERVICE_RUNNING;
        Win32::Daemon::State( SERVICE_RUNNING );
    }

    sub Callback_Pause
    {
        my( $Event, $Context ) = @_;
        $Context->{last_state} = SERVICE_PAUSED;
        Win32::Daemon::State( SERVICE_PAUSED );
    }

    sub Callback_Continue
    {
                if( SERVICE_CONTINUE_PENDING == Win32::Daemon::State() )
                {
                        my( $Event, $Context ) = @_;
                        $Context->{last_state} = SERVICE_RUNNING;
                        Win32::Daemon::State( SERVICE_RUNNING );
                }
                else
                {
                        Win32::Daemon::State(SERVICE_CONTINUE_PENDING);
                }
        }

    sub Callback_Stop
    {
        my( $Event, $Context ) = @_;
        $Context->{last_state} = SERVICE_STOPPED;
        Win32::Daemon::State( SERVICE_STOPPED );
        
        # We need to notify the Daemon that we want to stop callbacks and the 
service.
        Win32::Daemon::StopService();
    }

Reply via email to