[Win32utils-devel] Another patch of win32-service for nice startup.

Park Heesob phasis at nownuri.net
Sat Nov 26 10:50:53 EST 2005


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








More information about the win32utils-devel mailing list