Beispiel #1
0
void
omni_thread::start(void)
{
    omni_mutex_lock l(mutex);

    if (_state != STATE_NEW)
    throw omni_thread_invalid();

#ifndef __BCPLUSPLUS__
    // MSVC++ or compatiable
    unsigned int t;
    handle = (HANDLE)_beginthreadex(
                        NULL,
            0,
            omni_thread_wrapper,
            (LPVOID)this,
            CREATE_SUSPENDED, 
            &t);
    nt_id = t;
    if (handle == NULL)
      throw omni_thread_fatal(GetLastError());
#else
    // Borland C++
    handle = (HANDLE)_beginthreadNT(omni_thread_wrapper,
                    0,
                    (void*)this,
                    NULL,
                    CREATE_SUSPENDED,
                    &nt_id);
    if (handle == INVALID_HANDLE_VALUE)
      throw omni_thread_fatal(errno);
#endif

    if (!SetThreadPriority(handle, nt_priority(_priority)))
      throw omni_thread_fatal(GetLastError());

    if (ResumeThread(handle) == 0xffffffff)
    throw omni_thread_fatal(GetLastError());

    _state = STATE_RUNNING;
}
Beispiel #2
0
// -------------------------------------------------------------------------
//
void KsNtServiceServer::serviceMain(int argc, char **argv)
{
    //
    // First, create some signaling objects. The _one_shot_event signals
    // the serviceRun() task that it should wake up and iterate once again,
    // thus spinning up the KS server, and process requests. The next event,
    // _service_done_event, signals, that the whole service task (executable)
    // is now ready to cease.
    //
    _service_done_event = CreateEvent(0, FALSE, FALSE, 0);
    _one_shot_event     = CreateEvent(0, FALSE, FALSE, 0);
    if ( !_service_done_event || !_one_shot_event ) {
        lastError("Can't initialize signaling mechanism");
    }
    //
    // Next, register the service controller. Remember, that only after we've
    // done this, we can report the service status to the service manager.
    //
    _service_status_handle = RegisterServiceCtrlHandler(
                                 (LPCTSTR) _service_name,
                                 (LPHANDLER_FUNCTION) ks_c_serviceController);
    if ( !_service_status_handle ) {
        lastError("Can't register service control handler");
        return;
    }
    //
    // Next, we ask the developer for a KS server object, which will be
    // subsequently used within the real workhorse thread.
    //
    reportServiceStatus(SERVICE_START_PENDING, NO_ERROR, 0, 1, _create_to);
    _my_server = createServer((int) argc, (char **) argv);
    if ( !_is_ok || (_my_server == 0) || !_my_server->isOk() ) {
    	_is_ok = false;
        PltLog::Error("abnormal service termination");
        return;
    }
    verbose("Created server object successfully");
    reportServiceStatus(SERVICE_START_PENDING, NO_ERROR, 0, 2, _spinup_to);
    //
    // We must use the apropriate function from the C++ RTL here, as we will
    // otherwise get memory leaks. As if NT wouldn't be the biggest memory
    // leak ever created by menkind...
    //
#if PLT_COMPILER_MSVC
    _workhorse_thread = (HANDLE) _beginthread(
        (void (*)(void *)) ks_c_serviceRun,    // entry point of new thread
        0,                                     // stack size (default)
        0);                                    // arguments (none)
#else
# if PLT_COMPILER_BORLAND
    _workhorse_thread = (HANDLE) _beginthreadNT(
        (void (*)(void *)) ks_c_serviceRun, // entry point of new thread
        32768,                           // initial stack size
        0,                               // no arguments to pass to thread
        0,                               // no security, as NT hasn't one...
        0,                               // spin up thread immediately
        &_workhorse_thread_id);
# else
#  error "Don't know how to start threads"
# endif
#endif

    if ( _workhorse_thread <= 0) {
    	_is_ok = false;
        PltLog::Error("Can't start service thread");
        return;
    }
    verbose("Started service thread");
    //
    // Gosh! Finally, we're up and running. Yeah, I can't believe it!
    //
    reportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0, 0);
    if ( WaitForSingleObject(_service_done_event, INFINITE) !=
            WAIT_OBJECT_0 ) {
        PltLog::Warning("\"Service Done\" signaling failed");
    }
    verbose("Service thread woken up");
    if ( !TerminateThread(_workhorse_thread, 0) ) {
    	lastError("Can't terminate service thread");
    }
    if ( _my_server ) {
        delete _my_server; _my_server = 0;
    }
    //
    // Simply terminate. This will throw us back to the main thread.
    //
    reportServiceStatus(SERVICE_STOPPED,
                        _service_status.dwWin32ExitCode,
                        _service_status.dwServiceSpecificExitCode, 0, 0);
} // KsNtServiceServer::serviceMain
Beispiel #3
0
// -------------------------------------------------------------------------
//
//
void KsW95ServiceServer::run()
{
    if ( _is_ok ) {

	if ( _service_done_event == 0 ) {
	    _service_done_event = CreateEvent(0, FALSE, FALSE, 0);
	    if ( _service_done_event == 0 ) {
		_is_ok = false;
		PltLog::Error("Can't initialize signalling mechanism");
		return;
	    }
	}

	_my_server = createServer(_argc, _argv);
	if ( !_is_ok || (_my_server == 0) || !_my_server->isOk() ) {
	    _is_ok = false;
	    PltLog::Error("abnormal service termination");
	    return;
	}

	DWORD thread_id;
    //
    // We must use the apropriate function from the C++ RTL here, as we will
    // otherwise get memory leaks. As if NT wouldn't be the biggest memory
    // leak ever created by menkind...
    //
#if PLT_COMPILER_MSVC
    _workhorse_thread = (HANDLE) _beginthread(
        (void (*)(void *)) ks_c_w95serviceRun,    // entry point of new thread
        0,                                        // stack size (default)
        0);                                       // arguments (none)
#elif PLT_COMPILER_BORLAND
	_workhorse_thread = (HANDLE) _beginthreadNT(
           (void (*)(void *)) ks_c_w95serviceRun,
	   32768,
	   0,
	   0,
	   0,
	   &thread_id);
#else
# error "Don't know how to start threads"
#endif
	_workhorse_thread_id = thread_id;
        if ( _workhorse_thread <= 0 ) {
            _is_ok = false;
            PltLog::Error("Can't start service thread");
            return;
        }
        verbose("Service thread started");
	//
	// Now keep on going, dispatching messages until we'll notify
	// ourself to quit the game.
	//
	MSG messageForYouSir;
	while ( GetMessage(&messageForYouSir, 0, 0, 0) > 0 ) {
	    DispatchMessage(&messageForYouSir);
	}

        if ( _workhorse_thread > 0 ) {
            TerminateThread(_workhorse_thread, 0);
        }
        _workhorse_thread = 0;

	if ( _my_server ) {
            delete _my_server; _my_server = 0;
        }
    }
} // KsW95ServiceServer::run