Park Heesob
2005-Nov-26 15:50 UTC
[Win32utils-devel] Another patch of win32-service for nice startup.
Hi,
I believe this patch would be a perfect solution for a lengthy
initialization application.
Added hStartEvent, service_init, checkpoint increments.
===========================================================--- temp/service.c
2005-11-27 00:03:30.000000000 +0900
+++ service.c 2005-11-27 00:01:58.000000000 +0900
@@ -14,6 +14,7 @@
static VALUE cDaemonError;
static VALUE rbServiceStruct, rbServiceStatusStruct;
+static HANDLE hStartEvent;
static HANDLE hStopEvent;
static SERVICE_STATUS_HANDLE ssh;
static DWORD dwServiceState;
@@ -33,6 +34,7 @@
{
DWORD bRet;
DWORD dwWaitRes;
+ int i;
// Obtain the name of the service.
LPTSTR lpszServiceName = lpszArgv[0];
@@ -46,6 +48,15 @@
rb_raise(cDaemonError,"RegisterServiceCtrlHandler failed");
}
+ // wait for sevice initialization
+ for(i=1;TRUE;i++)
+ {
+ if(WaitForSingleObject(hStartEvent, 1000) == WAIT_OBJECT_0)
+ break;
+
+ SetTheServiceStatus(SERVICE_START_PENDING, 0, i, 1000);
+ }
+
// The service has started.
SetTheServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0);
@@ -241,9 +252,9 @@
}
#endif
- // Create Thread for service main
- hThread = CreateThread(NULL,0,ThreadProc,0,0,&ThreadId);
- if(hThread == INVALID_HANDLE_VALUE){
+ // Create the event to signal the service to start.
+ hStartEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if(hStartEvent == NULL){
strcpy(error,ErrorDescription(GetLastError()));
ErrorStopService();
rb_raise(cDaemonError,error);
@@ -257,11 +268,20 @@
rb_raise(cDaemonError,error);
}
- // Wait for SERVICE_RUNNING
- while(dwServiceState != SERVICE_RUNNING){
- sleep(10);
+ // Create Thread for service main
+ hThread = CreateThread(NULL,0,ThreadProc,0,0,&ThreadId);
+ if(hThread == INVALID_HANDLE_VALUE){
+ strcpy(error,ErrorDescription(GetLastError()));
+ ErrorStopService();
+ rb_raise(cDaemonError,error);
+ }
+
+ if(rb_respond_to(self,rb_intern("service_init"))){
+ rb_funcall(self,rb_intern("service_init"),0);
}
+ SetEvent(hStartEvent);
+
// Call service_main method
if(rb_respond_to(self,rb_intern("service_main"))){
rb_funcall(self,rb_intern("service_main"),0);
=======================================================
I tested with the code of 400 seconds initialization and work fine.
def service_init
for i in 1..20
File.open("c:\\test2.log","a+"){ |f|
f.puts("#{i}") }
sleep 20
end
end
Regards,
Park Heesob
Daniel Berger
2005-Nov-27 00:32 UTC
[Win32utils-devel] Another patch of win32-service for nice startup.
Excellent. Patch committed. I''ll have a release out tonight or tomorrow. Thanks! Dan Park Heesob wrote:>Hi, > >I believe this patch would be a perfect solution for a lengthy >initialization application. >Added hStartEvent, service_init, checkpoint increments. > >===========================================================>--- temp/service.c 2005-11-27 00:03:30.000000000 +0900 >+++ service.c 2005-11-27 00:01:58.000000000 +0900 >@@ -14,6 +14,7 @@ > static VALUE cDaemonError; > static VALUE rbServiceStruct, rbServiceStatusStruct; > >+static HANDLE hStartEvent; > static HANDLE hStopEvent; > static SERVICE_STATUS_HANDLE ssh; > static DWORD dwServiceState; >@@ -33,6 +34,7 @@ > { > DWORD bRet; > DWORD dwWaitRes; >+ int i; > > // Obtain the name of the service. > LPTSTR lpszServiceName = lpszArgv[0]; >@@ -46,6 +48,15 @@ > rb_raise(cDaemonError,"RegisterServiceCtrlHandler failed"); > } > >+ // wait for sevice initialization >+ for(i=1;TRUE;i++) >+ { >+ if(WaitForSingleObject(hStartEvent, 1000) == WAIT_OBJECT_0) >+ break; >+ >+ SetTheServiceStatus(SERVICE_START_PENDING, 0, i, 1000); >+ } >+ > // The service has started. > SetTheServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0); > >@@ -241,9 +252,9 @@ > } > #endif > >- // Create Thread for service main >- hThread = CreateThread(NULL,0,ThreadProc,0,0,&ThreadId); >- if(hThread == INVALID_HANDLE_VALUE){ >+ // Create the event to signal the service to start. >+ hStartEvent = CreateEvent(NULL, TRUE, FALSE, NULL); >+ if(hStartEvent == NULL){ > strcpy(error,ErrorDescription(GetLastError())); > ErrorStopService(); > rb_raise(cDaemonError,error); >@@ -257,11 +268,20 @@ > rb_raise(cDaemonError,error); > } > >- // Wait for SERVICE_RUNNING >- while(dwServiceState != SERVICE_RUNNING){ >- sleep(10); >+ // Create Thread for service main >+ hThread = CreateThread(NULL,0,ThreadProc,0,0,&ThreadId); >+ if(hThread == INVALID_HANDLE_VALUE){ >+ strcpy(error,ErrorDescription(GetLastError())); >+ ErrorStopService(); >+ rb_raise(cDaemonError,error); >+ } >+ >+ if(rb_respond_to(self,rb_intern("service_init"))){ >+ rb_funcall(self,rb_intern("service_init"),0); > } > >+ SetEvent(hStartEvent); >+ > // Call service_main method > if(rb_respond_to(self,rb_intern("service_main"))){ > rb_funcall(self,rb_intern("service_main"),0); >=======================================================> >I tested with the code of 400 seconds initialization and work fine. > > def service_init > for i in 1..20 > File.open("c:\\test2.log","a+"){ |f| f.puts("#{i}") } > sleep 20 > end > end > > >Regards, > >Park Heesob > > > > > > >_______________________________________________ >win32utils-devel mailing list >win32utils-devel at rubyforge.org >http://rubyforge.org/mailman/listinfo/win32utils-devel > > >