views:

296

answers:

1

Hey, im doing some client/server stuff in a windows service. Pretty much new to this stuff.

The problem I'm encountering is that when I try to stop the service through Service Manager, it crashes. I added some MessageBoxes code, to trace where they are crashing and I found that when it closes the listener socket it crashes!!!

I tried to run the service as a console application, and by myself called the function which is called SERVICE__CONTROL__STOP event is received so that I may reproduce the bug and debug easily. But it is working fine. The windows service is only crashing when I stop it through Service Manager

Here is some code

The main function

int main(int argc, char* argv[])
{   
 // Create the service object
    CTestService CustomServiceObject;

    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
     std::cerr << "MFC failed to initialize!" << std::endl;
     return 1;
    }

    // Parse for standard arguments (install, uninstall, version etc.)
    if (! CustomServiceObject.ParseStandardArgs(argc, argv)) 
    {
        // StartService() calls ::StartServiceCtrlDispatcher() 
    // with the ServiceMain func and stuff
        CustomServiceObject.StartService();
    }

    // When we get here, the service has been stopped
    return CustomServiceObject.m_Status.dwWin32ExitCode;
}

The Service Handler callback function

// static member function (callback) to handle commands from the
// service control manager
void CNTService::Handler(DWORD dwOpcode)
{
    // Get a pointer to the object
    CNTService* pService = m_pThis;

    pService->DebugMsg("CNTService::Handler(%lu)", dwOpcode);
    switch (dwOpcode) {
    case SERVICE_CONTROL_STOP: // 1
        pService->SetStatus(SERVICE_STOP_PENDING);
        pService->OnStop();

    // ..
    // .. 
    // other event handling
    // ..
    // ..
}

the OnStop() function

void CTestService::OnStop()
{
    m_sListener.ShutDown(2);
    m_sConnected.ShutDown(2);

    MessageBox(NULL, "After Shutdown", NULL, IDOK); 

    m_sConnected.Close();

    MessageBox(NULL, "Closed connected socket", NULL, IDOK); 

    // crashes here when I try to stop through service manager
    // but if I run as console application works fine and terminates successfully
    m_sListener.Close();

    MessageBox(NULL, "Closed listener socket", NULL, IDOK); 

    ::PostThreadMessage(m_dwThreadID, WM_QUIT, NULL, NULL);

    MessageBox(NULL, "After PostThreadMessage", NULL, IDOK);
}

EDIT: If a connection is made (client connects to the server) and the client closes the connection and then the service is stopped nothing crashes. It only crashes if the socket is listening and no connection is accepted or the client doesnt closes the connection and the service is stopped :)

I guess its clear!

A: 

The problem is that you're most likely using the socket from multiple threads. Multiple threads and CAsyncSocket do not mix - in fact, as noted by the documentation.

Usually you would push the socket into it's own Worker Thread then you would signal it to close when you needed it to.

Lee
My service is single threaded. I dont know if MFC internally or a Windows Service internally creates another thread for its operation
hab
An easy way to check for sure would be to use GetCurrentThreadId(). Simply log the result where the socket is created/initialized and the again where the socket is closed (your OnStop routine). Then run your service and see what the results are. If the values are different, then there is more than one thread touching that code.
TheUndeadFish
Okay, just tried this, but no the thread IDs were the same, so there is only one thread in action.
hab