I have a service that under some circumstances needs
extended time to comply to a service stop request (I am
specifically *not* talking on a system shutdown
notification here). The reason is that there might be
large amounts of data in main memory which need to be
persisted before the service is shut down.
Right now, I am calling SetServiceStatus repitetivly with
SERVICE_STOP_PENDING and incremented dwCheckPoint.
HOWEVER, the service process is *always* terminted after
60 seconds.
This sounds like there is a hard-coded restriction in the
SCM that prevents services from running for more than 60
seconds after the stop request. Is this true? Is there
any way to circumvent this? Or am I just dumb enough to
do it right ;-). If the later is the case, I am glad to
hear how to do it.
Oh, yes, one thing: I know that the service should
respond quickly to the STOP request. It typically does,
but this is a real-time application with highest priority
of receiving all incoming events. So the receiver has
highest priority and buffers all messages in memory. As
soon as there is time left, they are persisted. However,
with very large burst this can be lengthy and our goal is
to make sure it is capable to persist it when a "normal"
stop request occurs.
Any help is greatly appreciated.
Rainer Gerhards
>
> I have a service that under some circumstances needs
> extended time to comply to a service stop request (I am
> specifically *not* talking on a system shutdown
> notification here). The reason is that there might be
> large amounts of data in main memory which need to be
> persisted before the service is shut down.
>
> Right now, I am calling SetServiceStatus repitetivly with
> SERVICE_STOP_PENDING and incremented dwCheckPoint.
> HOWEVER, the service process is *always* terminted after
> 60 seconds.
Its not enough to simply check in periodicallly by calling
SetServiceStatus(). You need to make sure you are initially setting the
service status to SERVICE_STOP_PENDING with a wait hint of perhaps 1000.
Then, every second thereafter, reset the wait hint with an increasingly
larger value. This is important! When setting a value for stop pending,
the wait hint must be additive. 1000, 2000, 3000, ... This is different
than when setting the wait hint for other service statii.
If you are already using this algorithm, or if you try it and still get
terminated after 60 seconds, let me know and I'll try to track down the
cause.
Regards,
Jonathan
This posting is provided "AS IS" with no warranties, and confers no rights.
many thanks for your reply. I initially did not increment
the wait time, but now I do and still get terminated
after 60 seconds.
I now initially set the dwWait hint to 5000 and then call
in every seconds and increment it by 1000. Please note
that the first increment happens at shutdownbegin+1000,
so after 1 second I set the wait hint to 6000 and so on -
so it is always at least 4000 ms away.
The code that does the increment looks as follows:
pService->m_Status.dwCheckPoint++;
pService->m_Status.dwWaitHint += 1000;
char szt[512]; wsprintf(szt, "Status checkpoint:
dwCheckPoint: %d, dwWaitHint: %d, dwState: %d\n",
pService->m_Status.dwCheckPoint, pService-
>m_Status.dwWaitHint, pService->m_Status.dwCurrentState);
OutputDebugString(szt);
::SetServiceStatus(pService->m_hServiceStatus,
&pService->m_Status);
I have used the OutputDebugStrings to verify that the
values are indeed what I think they should be ;-)
Any additional help is greatly appreciated.
All the best,
Rainer
>.
>
I understand what is happening now....
On Windows 2000, after 30 seconds, the SCM checks to see if the Service
Control Handler thread has returned from its SERVICE_CONTROL_STOP
processing. If the service control handler thread has not returned, the SCM
waits another 30 seconds. If the thread still has not returned, the SCM
assumes it is hung. In that case, you should see the following error in
the "System" event log.
Timeout (30000 milliseconds) waiting for a transaction response from the
<ServiceName> service.
with Event ID 7011 and Source "Service Control Manager".
This timeout can be configured on Windows 2000 globally by creating a
REG_DWORD registry value named "ServicesPipeTimeout" in milliseconds, under
the following registry key.
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control
If this value is not present, the system assumes a default value of 30000
(30 seconds). This value is read from the registry at system startup, so
you will need to add/modify the value when you install your service and
then it should be honored the next time you reboot.
I will work on getting this into the formal documentation, or at least into
a KB article.
I am Andre Lorbach, also part of the Adiscon developer team. Rainer also
asked me to look into this problem.
And I found another workaround without this registry setting you described
below.
I noticed that the "dwCheckPoint" and "dwWaitHint" were set directly after
the SCM sent the "SERVICE_CONTROL_STOP" command.
It seems like that the SCM kills the service after 61 seconds, doesn't
matter how ofter you increment dwCheckPoint and dwWaitHint.
What I have then done was removing the shutdown procedure to the position
where the SCM sends the "SERVICE_CONTROL_SHUTDOWN" command.
And this solved the problem. In my test environment, the service was not
killed and shutdown correctly after 10 minutes ;-).
Best regards,
Andre Lorbach
Adiscon GmbH
""Jonathan Russ [MS]"" <jr...@online.microsoft.com> wrote in message
news:AqiVnr7FCHA.2408@cpmsftngxa08...