void cms_clientFree( cms_client client) { struct soap* soap; cms_soapThread soapThread; cms_thread(client)->terminate = TRUE; os_mutexLock(&client->conditionMutex); os_condSignal(&client->condition); os_mutexUnlock(&client->conditionMutex); cms_threadDeinit(cms_thread(client)); if(client->soapEnvs){ os_mutexLock(&client->soapMutex); soap = (struct soap*)(c_iterTakeFirst(client->soapEnvs)); while(soap){ soap->error = soap_receiver_fault(soap, "Service is terminating.", NULL); soap_send_fault(soap); soap_destroy(soap); soap_end(soap); soap_done(soap); os_free(soap); soap = (struct soap*)(c_iterTakeFirst(client->soapEnvs)); } c_iterFree(client->soapEnvs); client->soapEnvs = NULL; os_mutexUnlock(&client->soapMutex); } if(client->threads){ soapThread = cms_soapThread(c_iterTakeFirst(client->threads)); while(soapThread){ cms_soapThreadFree(soapThread); (void)u_observableAction(u_observable(client->service->uservice), cms_clientStatisticsThreadRemove, client->service); soapThread = cms_soapThread(c_iterTakeFirst(client->threads)); } c_iterFree(client->threads); client->threads = NULL; } os_mutexDestroy(&client->soapMutex); os_mutexDestroy(&client->threadMutex); os_mutexDestroy(&client->conditionMutex); os_condDestroy(&client->condition); client->initCount = 0; if(client->service->configuration->verbosity >= 5){ OS_REPORT(OS_INFO, CMS_CONTEXT, 0, "Client thread stopped for IP: %d.%d.%d.%d", (int)(client->ip>>24)&0xFF, (int)(client->ip>>16)&0xFF, (int)(client->ip>>8)&0xFF, (int)(client->ip&0xFF)); }
cms_client cms_clientNew( unsigned long ip, cms_service service) { cms_client client; os_result osr; client = os_malloc(sizeof *client); if(client != NULL){ if (cms_threadInit(cms_thread(client), "cms_client", &service->configuration->clientScheduling)) { cms_object(client)->kind = CMS_CLIENT; cms_thread(client)->did = service->did; cms_thread(client)->uri = os_strdup(service->uri); client->ip = ip; client->initCount = 0; client->service = service; client->internalFree = FALSE; osr = os_mutexInit(&client->soapMutex, NULL); client->soapEnvs = c_iterNew(NULL); if(osr == os_resultSuccess){ osr = os_mutexInit(&client->conditionMutex, NULL); if(osr == os_resultSuccess){ osr = os_condInit(&client->condition, &client->conditionMutex, NULL ); if(osr == os_resultSuccess){ osr = os_mutexInit(&client->threadMutex, NULL); if(osr == os_resultSuccess){ client->threads = c_iterNew(NULL); } else { cms_clientFree(client); } } } else { cms_clientFree(client); } } else { cms_clientFree(client); } } else { cms_clientFree(client); client = NULL; } } if(client == NULL){ if(service->configuration->verbosity >= 1){ OS_REPORT(OS_ERROR, CMS_CONTEXT, 0, "cms_clientNew: client could not be initialized."); } } return client; }
static void* cms_serviceCollectGarbage( void* arg) { cms_service cms; os_time update; cms_thread client; c_bool garbagePresent; cms = cms_service(arg); update.tv_sec = 2; update.tv_nsec = 0; garbagePresent = FALSE; /* * Keep going until service terminates AND all garbage has been collected. */ while((cms->terminate == FALSE) || (c_iterLength(cms->clientGarbage) != 0)) { os_mutexLock(&cms->clientMutex); client = cms_thread(c_iterTakeFirst(cms->clientGarbage)); os_mutexUnlock(&cms->clientMutex); while(client != NULL) { /* * Call threadFree and NOT clientFree on purpose. */ cms_threadFree(client); os_mutexLock(&cms->clientMutex); client = cms_thread(c_iterTakeFirst(cms->clientGarbage)); os_mutexUnlock(&cms->clientMutex); garbagePresent = TRUE; } if((c_iterLength(cms->clients) == 0) && (garbagePresent == TRUE)) { if(cms->configuration->verbosity >= 3) { OS_REPORT(OS_INFO, CMS_CONTEXT, 0, "No clients connected. Performing some garbage collecting..."); } cmx_deregisterAllEntities(); garbagePresent = FALSE; } if(cms->terminate == FALSE) { os_nanoSleep(update); } } c_iterFree(cms->clientGarbage); return NULL; }
cms_soapThread cms_soapThreadNew( const c_char* name, cms_client client) { cms_soapThread thread; os_mutexAttr attr; os_condAttr condAttr; os_result osr; thread = NULL; osr = os_resultInvalid; if(client != NULL){ thread = cms_soapThread(os_malloc(C_SIZEOF(cms_soapThread))); if (thread != NULL) { cms_object(thread)->kind = CMS_SOAPTHREAD; cms_threadInit(cms_thread(thread), name, &client->service->configuration->clientScheduling); cms_thread(thread)->uri = os_strdup(cms_thread(client)->uri); thread->client = client; thread->soap = NULL; osr = os_mutexAttrInit(&attr); if(osr == os_resultSuccess){ attr.scopeAttr = OS_SCOPE_PRIVATE; osr = os_mutexInit(&thread->soapMutex, &attr); if(osr == os_resultSuccess){ osr = os_condAttrInit(&condAttr); if(osr == os_resultSuccess){ condAttr.scopeAttr = OS_SCOPE_PRIVATE; osr = os_condInit(&thread->condition, &thread->soapMutex, &condAttr ); } } } } } if (osr != os_resultSuccess) { cms_soapThreadFree(thread); return NULL; } return thread; }
c_bool cms_soapThreadHandleRequest( cms_soapThread thread, struct soap* soap) { c_bool result; if(cms_thread(thread)->terminate == FALSE){ os_mutexLock(&thread->soapMutex); cms_thread(thread)->ready = FALSE; thread->soap = soap; os_condSignal(&thread->condition); os_mutexUnlock(&thread->soapMutex); result = TRUE; } else { result = FALSE; } return result; }
void cms_soapThreadFree( cms_soapThread thread) { if(thread->client->service->configuration->verbosity >= 6){ OS_REPORT_1(OS_INFO, CMS_CONTEXT, 0, "Stopping soapThread '%s'...", cms_thread(thread)->name); } os_mutexLock(&thread->soapMutex); cms_thread(thread)->terminate = TRUE; os_condSignal(&thread->condition); os_mutexUnlock(&thread->soapMutex); cms_threadDeinit(cms_thread(thread)); if(thread->client->service->configuration->verbosity >= 6){ OS_REPORT_1(OS_INFO, CMS_CONTEXT, 0, "soapThread '%s' stopped.", cms_thread(thread)->name); } os_condDestroy(&thread->condition); os_mutexDestroy(&thread->soapMutex); os_free(cms_thread(thread)->uri); os_free(thread); }
cms_client cms_serviceLookupClient( cms_service cms, struct soap* soap, const c_char* uri) { int i; cms_client client; cms_client result; result = NULL; os_mutexLock(&cms->clientMutex); for(i=0; i<c_iterLength(cms->clients) && result == NULL; i++) { client = cms_client(c_iterObject(cms->clients, i)); if(client->ip == soap->ip) { if(cms_thread(client)->terminate == FALSE) { result = client; } } } if( (result == NULL) && (((c_ulong)c_iterLength(cms->clients)) < cms->configuration->maxClients)) { result = cms_clientNew(soap->ip, cms, uri); cms->clients = c_iterInsert(cms->clients, result); cms_clientStart(result); cms_serviceUpdateStatistics(cms); if(cms->configuration->verbosity >= 4) { OS_REPORT_4(OS_INFO, CMS_CONTEXT, 0, "Client thread started for IP: %d.%d.%d.%d", (int)(result->ip>>24)&0xFF, (int)(result->ip>>16)&0xFF, (int)(result->ip>>8)&0xFF, (int)(result->ip&0xFF)); }
c_bool cms_soapThreadStart( cms_soapThread thread) { return cms_threadStart(cms_thread(thread), cms_soapThreadRun, (void*)thread); }
static void* cms_soapThreadRun( void *thr) { cms_soapThread thread; struct soap* soap; c_char* result; thread = cms_soapThread(thr); os_mutexLock(&thread->soapMutex); while(cms_thread(thread)->terminate == FALSE){ if(thread->soap != NULL){ soap = thread->soap; thread->soap = NULL; cms_thread(thread)->results = NULL; soap->user = thr; soap_serve(soap); soap_destroy(soap); soap_end(soap); soap_done(soap); free(soap); u_entityAction( u_entity(thread->client->service->uservice), cms_soapThreadStatisticsRequestHandledAdd, thread->client->service); if(cms_thread(thread)->results != NULL){ result = (c_char*)(c_iterTakeFirst(cms_thread(thread)->results)); while(result){ os_free(result); result = (c_char*)(c_iterTakeFirst(cms_thread(thread)->results)); } c_iterFree(cms_thread(thread)->results); cms_thread(thread)->results = NULL; } } if(cms_thread(thread)->terminate == FALSE){ cms_thread(thread)->ready = TRUE; if(thread->client->service->configuration->verbosity >= 7){ OS_REPORT_1(OS_INFO, CMS_CONTEXT, 0, "soapThread '%s' ready.", cms_thread(thread)->name); } os_condWait(&thread->condition, &thread->soapMutex); if(thread->client->service->configuration->verbosity >= 7){ OS_REPORT_1(OS_INFO, CMS_CONTEXT, 0, "soapThread '%s' condition triggered.", cms_thread(thread)->name); } } } os_mutexUnlock(&thread->soapMutex); if(thread->client->service->configuration->verbosity >= 6){ OS_REPORT_1(OS_INFO, CMS_CONTEXT, 0, "soapThread '%s' ends.", cms_thread(thread)->name); } return NULL; }
cms_client cms_clientNew( unsigned long ip, cms_service service, const c_char* uri) { cms_client client; os_result osr; os_mutexAttr attr; os_condAttr condAttr; client = cms_client(os_malloc(C_SIZEOF(cms_client))); cms_threadInit(cms_thread(client), "cms_client", &service->configuration->clientScheduling); if(client != NULL){ cms_object(client)->kind = CMS_CLIENT; cms_thread(client)->uri = os_strdup(uri); client->ip = ip; client->initCount = 0; client->service = service; client->internalFree = FALSE; osr = os_mutexAttrInit(&attr); if(osr == os_resultSuccess){ attr.scopeAttr = OS_SCOPE_PRIVATE; osr = os_mutexInit(&client->soapMutex, &attr); client->soapEnvs = c_iterNew(NULL); if(osr == os_resultSuccess){ osr = os_condAttrInit(&condAttr); if(osr == os_resultSuccess){ osr = os_mutexInit(&client->conditionMutex, &attr); if(osr == os_resultSuccess){ condAttr.scopeAttr = OS_SCOPE_PRIVATE; osr = os_condInit(&client->condition, &client->conditionMutex, &condAttr ); if(osr == os_resultSuccess){ osr = os_mutexInit(&client->threadMutex, &attr); if(osr == os_resultSuccess){ client->threads = c_iterNew(NULL); } else { cms_clientFree(client); } } } else { cms_clientFree(client); } } else { cms_clientFree(client); } } else { cms_clientFree(client); } } else { cms_clientFree(client); } } if(client == NULL){ if(service->configuration->verbosity >= 1){ OS_REPORT(OS_ERROR, CMS_CONTEXT, 0, "cms_clientNew: client could not be initialized."); } } return client; }
void cms_serviceFree( cms_service cms) { cms_client client; c_iter clientCopy; c_ulong i, size; if(cms != NULL) { if(cms->configuration != NULL) { if(cms->configuration->verbosity >= 2) { OS_REPORT(OS_INFO, CMS_CONTEXT, 0, "Terminating CMSOAP service..."); } } if(cms->uservice != NULL) { u_serviceChangeState(cms->uservice, STATE_TERMINATING); } cms->terminate = TRUE; if(cms->leaseThread != NULL) { cms_threadFree(cms->leaseThread); } if(cms->garbageCollector != NULL) { cms_threadFree(cms->garbageCollector); } if(cms->soap != NULL) { cms->soap->attributes = NULL; soap_destroy(cms->soap); soap_end(cms->soap); soap_done(cms->soap); free(cms->soap); } if(cms->clients != NULL) { os_mutexLock(&cms->clientMutex); clientCopy = c_iterCopy(cms->clients); os_mutexUnlock(&cms->clientMutex); if(c_iterLength(cms->clients) > 0) { if(cms->configuration->verbosity >= 2) { OS_REPORT_1(OS_WARNING, CMS_CONTEXT, 0, "Terminating CMSOAPService, but %d client(s) is/are still connected.", c_iterLength(cms->clients)); } } size = c_iterLength(clientCopy); for(i=0; i<size; i++) { client = cms_client(c_iterObject(clientCopy, i)); cms_thread(client)->terminate = TRUE; } for(i=0; i<size; i++) { client = cms_client(c_iterObject(clientCopy, i)); cms_clientFree(client); } c_iterFree(clientCopy); os_mutexLock(&cms->clientMutex); c_iterFree(cms->clients); os_mutexUnlock(&cms->clientMutex); os_mutexDestroy(&cms->clientMutex); } if(cms->configuration != NULL) { if(cms->configuration->verbosity >= 4) { OS_REPORT(OS_INFO, CMS_CONTEXT, 0, "CMSOAP service terminated."); } } cms_configurationFree(cms->configuration); if(cms->uservice != NULL) { cmx_deregisterAllEntities(); u_serviceChangeState(cms->uservice, STATE_TERMINATED); u_serviceFree(cms->uservice); } cmx_detach(); os_free(cms); } }