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 > > >