Changeset 391

Show
Ignore:
Timestamp:
11/20/06 10:05:34 (2 years ago)
Author:
luislavena
Message:

native_service: added a lot of hackish code until get a working version (very close now!).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/win32-native_service/projects/mongrel_service/native/mongrel_service.bas

    r377 r391  
    3434 
    3535namespace mongrel_service 
     36    Function GetErrorString(ByVal Code As UInteger, ByVal MaxLen As UShort = 1024) As String 
     37        Dim ErrorString         As Any PTR 
     38        Dim sError              As String 
     39        Dim lLen                As Integer 
     40         
     41        lLen = FormatMessage   (FORMAT_MESSAGE_FROM_SYSTEM Or _ 
     42                                FORMAT_MESSAGE_ALLOCATE_BUFFER, _ 
     43                                NULL, _ 
     44                                Code, _ 
     45                                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), _ 
     46                                @ErrorString, _ 
     47                                MaxLen, _ 
     48                                NULL) 
     49 
     50        If (ErrorString <> 0) Then 
     51         
     52            sError = Space(lLen - 2) 
     53            CopyMemory(StrPtr(sError), ByVal ErrorString, lLen-2) 
     54             
     55            LocalFree(ErrorString) 
     56        End If 
     57         
     58        Return sError 
     59    End Function 
     60 
    3661    sub debug(byref message as string) 
    3762        dim handle as integer 
     
    5782         
    5883        '# TODO: fix inheritance here 
    59         single_mongrel = @this 
     84        single_mongrel_ref = @this 
    6085    end constructor 
    6186     
     
    6893        debug("single_onInit()") 
    6994         
     95        '# due lack of inheritance, we use single_mongrel_ref as pointer to  
     96        '# SingleMongrel instance. now we should call StillAlive 
     97        self.StillAlive() 
     98        if (len(self.commandline) > 0) then 
     99            debug("starting child process with cmdline: " + self.commandline) 
     100            single_mongrel_ref->__child_pid = 0 
     101            single_mongrel_ref->__child_pid = spawn(self.commandline) 
     102            self.StillAlive() 
     103            debug("child process pid: " + str(single_mongrel_ref->__child_pid)) 
     104        end if 
     105         
     106        '# set as success, but we must evaluate this first! 
     107        result = -1 
     108         
    70109        debug("single_onInit() done") 
    71110        return result 
     
    74113    sub single_onStart(byref self as ServiceProcess) 
    75114        debug("single_onStart()") 
     115         
     116        do while (self.state = Running) or (self.state = Paused) 
     117            sleep 100 
     118        loop 
     119         
    76120        debug("single_onStart() done") 
    77121    end sub 
     
    79123    sub single_onStop(byref self as ServiceProcess) 
    80124        debug("single_onStop()") 
     125         
     126        '# now terminates the child process 
     127        if not (single_mongrel_ref->__child_pid = 0) then 
     128            debug("trying to kill pid: " + str(single_mongrel_ref->__child_pid)) 
     129            'if not (send_break(single_mongrel_ref->__child_pid) = 0) then 
     130            if not (terminate_spawned(single_mongrel_ref->__child_pid) = TRUE) then 
     131                debug("send_break() reported a problem when terminating process " + str(single_mongrel_ref->__child_pid)) 
     132            else 
     133                debug("child process terminated with success.") 
     134            end if 
     135        end if 
     136         
    81137        debug("single_onStop() done") 
    82138    end sub 
     
    88144                                                            "(c) 2006 The Mongrel development team.") 
    89145         
     146        '# allocate a new console (this is for services 
     147        if (AllocConsole() = 0) then 
     148            debug("success in AllocConsole()") 
     149        else 
     150            debug("AllocConsole failed, error: " + GetErrorString(GetLastError())) 
     151        end if 
     152         
     153        '# we need to get the Console hook prior adding our handler. 
     154        if not (GetCtrlRoutineAddress() = 0) then 
     155            debug("error GetCtrlRoutineAddress()") 
     156        end if 
     157         
    90158        '# add SingleMongrel (service) 
    91159        host.Add(simple.__service) 
     
    93161            '# call from Service Control Manager (SCM) 
    94162            case RunAsService: 
     163                debug("ServiceHost RunAsService") 
    95164                host.Run() 
    96165                 
    97166            '# call from console, useful for debug purposes. 
    98167            case RunAsConsole: 
     168                debug("ServiceController Console") 
    99169                ctrl.Console() 
    100170                 
  • branches/win32-native_service/projects/mongrel_service/native/mongrel_service.bi

    r377 r391  
    3333#define SERVICEFB_INCLUDE_UTILS 
    3434#include once "lib/ServiceFB/ServiceFB.bi" 
     35#include once "process.bi" 
    3536 
    3637namespace mongrel_service 
     
    5758     
    5859    '# TODO: replace with inheritance here 
    59     dim shared single_mongrel as SingleMongrel ptr 
     60    dim shared single_mongrel_ref as SingleMongrel ptr 
    6061end namespace 
  • branches/win32-native_service/projects/mongrel_service/native/process.bas

    r378 r391  
    3333#include once "process.bi" 
    3434 
     35private sub _dprint(byref message as string) 
     36    dim handle as integer 
     37     
     38    handle = freefile 
     39    open EXEPATH + "\process.log" for append as #handle 
     40     
     41    print #handle, message 
     42     
     43    close #handle 
     44end sub 
     45 
    3546function spawn(byref cmdLine as string) as uinteger 
    3647    dim result as uinteger 
     
    5263    '# StdIn 
    5364    if (CreatePipe( @StdInRd, @StdInWr, @sa, 0 ) = 0) then 
    54         print "Error creating StdIn pipes." 
     65        _dprint("Error creating StdIn pipes.") 
    5566        end 0 
    5667    end if 
     
    5869    '# StdOut 
    5970    if (CreatePipe( @StdOutRd, @StdOutWr, @sa, 0 ) = 0) then 
    60         print "Error creating StdOut pipes." 
     71        _dprint("Error creating StdOut pipes.") 
    6172        end 0 
    6273    end if 
     
    6475    '# StdErr 
    6576    if (CreatePipe( @StdErrRd, @StdErrWr, @sa, 0 ) = 0) then 
    66         print "Error creating StdErr pipes." 
     77        _dprint("Error creating StdErr pipes.") 
    6778        end 0 
    6879    end if 
     
    8394    '// INIT 
    8495     
    85     if (CreateProcess( NULL, _ 
    86                         StrPtr( cmdLine ), _ 
     96    if (CreateProcess(NULL, _ 
     97                        StrPtr(cmdLine), _ 
    8798                        NULL, _ 
    8899                        NULL, _ 
    89100                        TRUE, _ 
    90                         CREATE_NEW_PROCESS_GROUP or DETACHED_PROCESS, _ 
     101                        CREATE_NEW_PROCESS_GROUP, _                 '// CREATE_NEW_PROCESS_GROUP or DETACHED_PROCESS, _ 
    91102                        NULL, _ 
    92103                        NULL, _ 
    93104                        @si, _ 
    94                         @pi ) = 0) then 
     105                        @pi) = 0) then 
     106        _dprint("Error in CreateProcess (" + str(GetLastError())) 
    95107    else 
    96         CloseHandle( pi.hProcess
    97         CloseHandle( pi.hThread
     108        CloseHandle(pi.hProcess
     109        CloseHandle(pi.hThread
    98110        result = pi.dwProcessId 
     111        _dprint("Success in CreateProcess, PID " + str(result)) 
    99112    end if 
    100113     
    101114    return result 
    102115end function 
     116 
     117private function tricky_console_handler(byval dwCtrlType as DWORD) as BOOL 
     118    _dprint("tricky_console_handler got dwCtrlType = " + str(dwCtrlType)) 
     119    return (dwCtrlType = CTRL_C_EVENT) 
     120end function 
     121 
     122public function terminate_spawned(byval pid as uinteger) as BOOL 
     123    dim result as BOOL 
     124     
     125    result = FALSE 
     126     
     127    '# hook custom console_handler 
     128    SetConsoleCtrlHandler(@tricky_console_handler, TRUE) 
     129     
     130    '# fire CTRL_C_EVENT to all the children  
     131    if not (GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0) = 0) then 
     132        '# it worked 
     133        _dprint("GenerateConsoleCtrlEvent worked.") 
     134        result = TRUE 
     135    else 
     136        _dprint("GenerateConsoleCtrlEvent failed, error " + str(GetLastError())) 
     137    end if 
     138     
     139    '# we should check here if the pid no longer exist. 
     140    '# ... 
     141     
     142    '# remove our custom console handler 
     143    SetConsoleCtrlHandler(@tricky_console_handler, FALSE) 
     144     
     145    return result 
     146end function 
  • branches/win32-native_service/projects/mongrel_service/native/process.bi

    r378 r391  
    3535'# extern "C" from send_signal library 
    3636declare function send_break cdecl alias "send_break" (byval as uinteger) as integer 
     37declare function GetCtrlRoutineAddress cdecl alias "GetCtrlRoutineAddress" () as uinteger 
    3738 
    3839'# spawn(cmdline) => PID 
    3940declare function spawn(byref as string) as uinteger 
     41declare function console_handler(byval as DWORD) as BOOL 
     42declare function terminate_spawned(byval as uinteger) as BOOL 
  • branches/win32-native_service/projects/mongrel_service/native/send_signal.cpp

    r376 r391  
    9494 
    9595    // inject the thread 
     96    printf("creating remote thread\n"); 
    9697    hRemoteThread=CreateRemoteThread(hRemoteProc, NULL, 0, (LPTHREAD_START_ROUTINE)dwEntryPoint, (void *)CTRL_C_EVENT, CREATE_SUSPENDED, NULL); 
    9798    if (NULL==hRemoteThread) { 
     99        printf("cannot create thread\n"); 
    98100        _JumpLastError(rv, error, "CreateRemoteThread"); 
    99101    } 
    100102 
    101103    // wake up the thread 
     104    printf("wake up thread\n"); 
    102105    if (-1==ResumeThread(hRemoteThread)) { 
     106        printf("cannot wakeup thread\n"); 
    103107        _JumpLastError(rv, error, "ResumeThread"); 
    104108    } 
    105109 
    106110    // wait for the thread to finish 
     111    printf("waiting for signal...\n"); 
    107112    if (WAIT_OBJECT_0!=WaitForSingleObject(hRemoteThread, INFINITE)) { 
     113        printf("error waitforsingleobject\n"); 
    108114        _JumpLastError(rv, error, "WaitForSingleObject"); 
    109115    } 
    110116 
    111117    // find out what happened 
     118    printf("get exit code.\n"); 
    112119    if (!GetExitCodeThread(hRemoteThread, (DWORD *)&rv)) { 
     120        printf("GetExitCodeThread\n"); 
    113121        _JumpLastError(rv, error, "GetExitCodeThread"); 
    114122    } 
    115123 
     124    printf("GetExitCodeThread = %d\n", rv); 
    116125    if (STATUS_CONTROL_C_EXIT==rv) { 
    117         // printf("Target process was killed.\n"); 
     126        printf("Target process was killed.\n"); 
    118127        rv=EXIT_OK; 
    119128    } 
     
    254263 
    255264//-------------------------------------------------------------------- 
    256 RETVAL GetCtrlRoutineAddress(void) { 
     265extern "C" RETVAL GetCtrlRoutineAddress(void) { 
    257266    RETVAL rv=EXIT_OK; 
    258267 
     
    301310    HANDLE hRemoteProc=NULL; 
    302311    HANDLE hRemoteProcToken=NULL; 
    303  
    304     rv=GetCtrlRoutineAddress(); 
    305     _JumpIfError(rv, error, "GetCtrlRoutineAddress"); 
    306  
    307     // printf("Sending signal to process %d...\n", dwPid); 
     312     
     313    printf("send_break pid: %d\n", dwPid); 
     314     
     315    if (g_dwCtrlRoutineAddr==NULL) { 
     316        printf("getting CtrlRoutineAddress()...\n"); 
     317        rv=GetCtrlRoutineAddress(); 
     318        _JumpIfError(rv, error, "GetCtrlRoutineAddress"); 
     319    } 
     320     
     321    printf("Sending signal to process %d...\n", dwPid); 
    308322    rv=AdvancedOpenProcess(dwPid, &hRemoteProc); 
    309323    _JumpIfErrorStr(rv, error, "AdvancedOpenProcess", dwPid); 
    310324 
     325    printf("Start remote thread...\n"); 
    311326    rv=StartRemoteThread(hRemoteProc, g_dwCtrlRoutineAddr); 
    312327    _JumpIfError(rv, error, "StartRemoteThread");