int main( int argc, char* argv[]) { c_base base; int fileIndex = 1; c_bool scopedNames = FALSE; char osServiceName[SERVICE_NAME_MAX]; int id = os_procIdToInteger (os_procIdSelf()); if (argc < 2) { printf("Usage: %s [-m] <filename>\n", argv[0]); return -1; } snprintf(osServiceName, SERVICE_NAME_MAX, "%s%d", SERVICE_NAME_PREFIX, id); if (os_serviceStart(osServiceName) != os_resultSuccess) { printf("Failed to start mutex service\n"); return -2; } os_osInit(); if (strcmp(argv[1], "-m") == 0) { scopedNames =TRUE; fileIndex++; } base = c_create("preprocessor",NULL,0, 0); c_odlinit(c_module(base)); c_odlparse(argv[fileIndex]); c_gen_C(c_module(base), scopedNames); if (os_serviceStop() != os_resultSuccess) { printf("Failed to stop mutex service\n"); return -3; } return 0; }
/************************************************************** * Public functions **************************************************************/ c_bool u_serviceChangeState( u_service service, v_serviceStateKind newState) { u_result r; v_service s; c_bool result = FALSE; if (service != NULL) { result = u_entityReadClaim(u_entity(service), (v_entity*)(&s)); if (result == U_RESULT_OK) { assert(s); /* start or stop the Termination Monitor Thread */ if (newState == STATE_TERMINATING) { if (service->stt == NULL) { service->stt = u_serviceTerminationThreadNew(); } } if (newState == STATE_TERMINATED) { if (service->stt != NULL) { r = u_serviceTerminationThreadFree(service->stt); if (r != U_RESULT_OK) { OS_REPORT_1(OS_ERROR, "u_serviceChangeState", 0, "Failed to clean up the Service Termination Thread for process %d",os_procIdSelf()); } service->stt = NULL; } } result = v_serviceChangeState(s, newState); r = u_entityRelease(u_entity(service)); } else { OS_REPORT(OS_WARNING, "u_serviceChangeState", 0, "Could not claim service."); } } return result; }
/** \brief Figure out the identity of the current process * * os_procFigureIdentity determines the numeric, and if possible named * identity of a process. It will first check if the environment variable * SPLICE_PROCNAME is set (which is always the case if the process is started * via os_procCreate). If so, that value will be returned. Otherwise it will be * attempted to determine the commandline which started the process through the * procfs. If that fails, the PID will be returned. * * \param procIdentity Pointer to a char-buffer to which the result can be * written. If a name could be resolved, the result will * have the format "name <PID>". Otherwise it will just * be "<PID>". * \param procIdentitySize Size of the buffer pointed to by procIdentitySize * \return same as snprintf returns */ os_int32 os_procFigureIdentity( char *procIdentity, os_uint32 procIdentitySize) { os_int32 size = 0; char *process_name; size_t r = 0; int missingBytes = 0; process_name = os_getenv("SPLICE_PROCNAME"); if (process_name != NULL) { size = snprintf(procIdentity, procIdentitySize, "%s <%d>", process_name, os_procIdToInteger(os_procIdSelf())); } else { char *procPath; procPath = (char*) os_malloc(_OS_PROCESS_DEFAULT_CMDLINE_LEN_); if (procPath) { size = snprintf(procPath, _OS_PROCESS_DEFAULT_CMDLINE_LEN_, _OS_PROCESS_PROCFS_PATH_FMT_, os_procIdToInteger(os_procIdSelf())); if (size >= _OS_PROCESS_DEFAULT_CMDLINE_LEN_) { /* pid is apparently longer */ char *tmp = (char*) os_realloc(procPath, size + 1); if (tmp) { procPath = tmp; size = snprintf(procPath, size + 1, _OS_PROCESS_PROCFS_PATH_FMT_, os_procIdToInteger(os_procIdSelf())); } else { /* Memory-claim failed, revert to default (just pid) */ size = 0; } } /* procPath is set */ if (size > 0) { if (os_access(procPath, OS_ROK) == os_resultSuccess) { FILE *proc = fopen(procPath, "r"); if (proc) { do { r += fread((void*)&procIdentity[r], 1L, procIdentitySize-r,proc); } while( ferror(proc) && errno == EINTR ); /* Only count characters till the first null */ r = os_strnlen( procIdentity, r ); if ( r == procIdentitySize ) { char altbuffer[16]; int usefullRead; /* Buffer is full null terminate it */ procIdentity[r-1] = '\0'; /* There may be more bytes - count them*/ do { int p=0; do { p += fread((void*)&altbuffer, 1L, sizeof(altbuffer)-p,proc); } while( ferror(proc) && errno == EINTR ); usefullRead=os_strnlen(&altbuffer[0], sizeof(altbuffer)); missingBytes+=usefullRead; } while ( usefullRead == sizeof(altbuffer) ); /* Account for space before pid */ missingBytes++; } else if ( r > 1 ) { /* Add a space before the pid */ procIdentity[r++] = ' '; } fclose(proc); } } } os_free(procPath); } size = snprintf(&procIdentity[r], procIdentitySize-r, "<%d>", os_procIdToInteger(os_procIdSelf())); size = size+r+missingBytes; } return size; }
os_int32 os_procGetProcessName( char *procName, os_uint procNameSize) { char* process_name = NULL; char* procPath = NULL; int fileId; struct psinfo info; os_int32 size = 0; if (processName) { process_name = os_getenv("SPLICE_PROCNAME"); processName = (char*) os_malloc(_OS_PROCESS_DEFAULT_NAME_LEN_); *processName = "\0"; if (process_name != NULL) { size = snprintf(processName,_OS_PROCESS_DEFAULT_NAME_LEN_,"%s",process_name); } else { procPath = (char*) os_malloc(_OS_PROCESS_DEFAULT_CMDLINE_LEN_); if (procPath) { snprintf(procPath,_OS_PROCESS_DEFAULT_NAME_LEN_, _OS_PROCESS_PROCFS_PATH_FMT_, os_procIdSelf()); if ((fileId = open( procPath, O_RDONLY, 0555 )) >= 0) { if ( read( fileId, & info, sizeof(info) ) >= 0 ) { snprintf(processName,_OS_PROCESS_DEFAULT_NAME_LEN_,"%s",info.pr_fname); } } os_free(procPath); close( fileId ); } } } size = snprintf(procName, procNameSize, "%s", processName); return size; }
static void* shmMonitorMain( void* arg) { os_sharedHandle shmHandle; u_result cleanupResult; os_result result; os_duration blockingTime = 10*OS_DURATION_MILLISECOND; os_shmClient clients, client; s_shmMonitor _this = (s_shmMonitor)arg; os_procId ownPID; ownPID = os_procIdSelf(); shmHandle = u_domainSharedMemoryHandle( u_participantDomain( u_participant( splicedGetService(_this->spliceDaemon)))); os_mutexLock(&_this->mutex); while(_this->terminate == OS_FALSE){ clients = NULL; os_mutexUnlock(&_this->mutex); ut_threadAsleep(_this->thr, 1); result = os_sharedMemoryWaitForClientChanges(shmHandle, blockingTime, &clients); os_mutexLock(&_this->mutex); if(result == os_resultSuccess){ client = clients; _this->shmState = SHM_STATE_UNKNOWN; while(client){ if(client->state == OS_SHM_PROC_TERMINATED){ if(client->procId != ownPID){ OS_REPORT(OS_WARNING, OSRPT_CNTXT_SPLICED, 0, "Detected termination of process %d, that failed " "to clean up its resources before terminating. " "Attempting to clean up its resources now..." , client->procId); os_mutexUnlock(&_this->mutex); /* Allow the u_splicedCleanupProcessInfo() to take as * long as MAX(leasePeriod, serviceTerminatePeriod). * This is set in the threadsMonitor as the threads * interval. * By indicating that it'll sleep for 1 second, it * is allowed to stay dormant for that 1 second plus * the threads interval. */ ut_threadAsleep(_this->thr, 1); cleanupResult = u_splicedCleanupProcessInfo(splicedGetService(_this->spliceDaemon), client->procId); os_mutexLock(&_this->mutex); if(cleanupResult != U_RESULT_OK){ OS_REPORT(OS_FATAL, OSRPT_CNTXT_SPLICED, 0, "Cleaning up resources of terminated process " "%d failed, because process was modifying " "shared resources when it terminated, " "stopping domain now...", client->procId); _this->shmState = SHM_STATE_UNCLEAN; os_condSignal(&_this->cleanCondition); splicedSignalTerminate(_this->spliceDaemon, SPLICED_EXIT_CODE_RECOVERABLE_ERROR, SPLICED_SHM_NOK); } else { OS_REPORT(OS_INFO, OSRPT_CNTXT_SPLICED, 0, "Successfully cleaned up resources of " "terminated process %d.", client->procId); } } else { OS_REPORT(OS_FATAL, OSRPT_CNTXT_SPLICED, 0, "Detected unexpected detach of kernel by my own " "process, stopping domain now..."); _this->shmState = SHM_STATE_UNCLEAN; os_condSignal(&_this->cleanCondition); splicedSignalTerminate(_this->spliceDaemon, SPLICED_EXIT_CODE_RECOVERABLE_ERROR, SPLICED_SHM_NOK); } ut_threadAwake(_this->thr); } client = client->next; } os_shmClientFree(clients); if (_this->shmState == SHM_STATE_UNKNOWN) { _this->shmState = SHM_STATE_CLEAN; os_condSignal(&_this->cleanCondition); } } else if (result == os_resultUnavailable) { /* client list is empty so we need to give up some cpu time * in order that it can be initialised on non timesliced systems * e.g. vxworks kernel builds */ ut_sleep(_this->thr, 100*OS_DURATION_MICROSECOND); } } os_mutexUnlock(&_this->mutex); return NULL; }