void DisposeHttpListener(PHTTP_LISTENER listener) { ULONG state = InterlockedCompareExchange(&listener->State, HTTP_LISTENER_STATE_DISPOSING, HTTP_LISTENER_STATE_STARTED); if(state = HTTP_LISTENER_STATE_STOPPED) { return; } // Thread responsible for disposing the listener. if(state = HTTP_LISTENER_STATE_STARTED) { if(listener && listener->hRequestQueue) { for(int i=1; i<=listener->urlsCount; i++) { HttpRemoveUrlFromUrlGroup( listener->UrlGroupId, // Req Queue listener->urls[i], // Fully qualified URL NULL); } //Close the request queue. CloseHandle(listener->hRequestQueue); } // // Call HttpTerminate. // HttpTerminate(HTTP_INITIALIZE_SERVER, NULL); return; } else if (state == HTTP_LISTENER_STATE_DISPOSING) { // Only one thread can dispose the listener if(InterlockedCompareExchange(&listener->State, HTTP_LISTENER_STATE_STOPPED, HTTP_LISTENER_STATE_DISPOSING) == HTTP_LISTENER_STATE_DISPOSING) { // // Cleanup threadpool // HttpListenerCleanupThreadPool(listener); //Delete timers and release the IOContexts DeleteTimerQueueTimer(listener->TimerQueue, listener->FlushTimer,NULL); DeleteTimerQueue(listener->TimerQueue); HttpListenerFlushLookasideThreadProc(listener,NULL); // Free the listener FREE_MEM(listener); printf("Http listener terminated...\n"); } } }
void xmlrpc_server_httpsys( xmlrpc_env * const envP, const xmlrpc_server_httpsys_parms * const parmsP, unsigned int const parm_size ) { ULONG retCode; HANDLE hReqQueue = NULL; HTTPAPI_VERSION HttpApiVersion = HTTPAPI_VERSION_1; WCHAR wszURL[35]; XMLRPC_ASSERT_ENV_OK(envP); if (parm_size < XMLRPC_HSSIZE(authfn)) { xmlrpc_faultf(envP, "You must specify members at least up through " "'authfn' in the server parameters argument. " "That would mean the parameter size would be >= %u " "but you specified a size of %u", XMLRPC_HSSIZE(authfn), parm_size); return; } //Set logging options if (parmsP->logLevel>0) g_bDebug=TRUE; else g_bDebug=FALSE; if (parmsP->logLevel>1) g_bDebugString=TRUE; else g_bDebugString=FALSE; if (!parmsP->logFile) g_bDebug=FALSE; else StringCchPrintfA(g_fLogFile,MAX_PATH,parmsP->logFile); //construct the URL we are listening on if (parmsP->useSSL!=0) StringCchPrintf(wszURL,35,L"https://+:%u/RPC2",parmsP->portNum); else StringCchPrintf(wszURL,35,L"http://+:%u/RPC2",parmsP->portNum); global_registryP = parmsP->registryP; // Initialize HTTP APIs. retCode = HttpInitialize(HttpApiVersion, HTTP_INITIALIZE_SERVER, // Flags NULL // Reserved ); if (retCode != NO_ERROR) { xmlrpc_faultf(envP, "HttpInitialize failed with %lu", retCode); return; } // Create a Request Queue Handle retCode = HttpCreateHttpHandle(&hReqQueue, // Req Queue 0 // Reserved ); if (retCode != NO_ERROR) { xmlrpc_faultf(envP, "HttpCreateHttpHandle failed with %lu", retCode); goto CleanUp; } retCode = HttpAddUrl(hReqQueue, // Req Queue wszURL, // Fully qualified URL NULL // Reserved ); if (retCode != NO_ERROR) { xmlrpc_faultf(envP, "HttpAddUrl failed with %lu", retCode); goto CleanUp; } TraceW(L"we are listening for requests on the following url: %ws", wszURL); // Loop while receiving requests for(;;) { TraceW(L"Calling DoReceiveRequests()"); retCode = DoReceiveRequests(hReqQueue, parmsP); if(NO_ERROR == retCode) { TraceW(L"DoReceiveRequests() returned NO_ERROR, breaking"); break; } } CleanUp: TraceW(L"Tearing down the server.", wszURL); // Call HttpRemoveUrl for the URL that we added. HttpRemoveUrl( hReqQueue, wszURL ); // Close the Request Queue handle. if(hReqQueue) CloseHandle(hReqQueue); // Call HttpTerminate. HttpTerminate(HTTP_INITIALIZE_SERVER, NULL); return; }