DWORD LwSmTableAddEntry( PLW_SERVICE_INFO pInfo, PSM_TABLE_ENTRY* ppEntry ) { DWORD dwError = 0; BOOL bLocked = TRUE; PSM_TABLE_ENTRY pEntry = NULL; dwError = LwAllocateMemory(sizeof(*pEntry), OUT_PPVOID(&pEntry)); BAIL_ON_ERROR(dwError); LwSmLinkInit(&pEntry->link); LwSmLinkInit(&pEntry->waiters); pEntry->bValid = TRUE; dwError = LwSmCopyServiceInfo(pInfo, &pEntry->pInfo); dwError = LwMapErrnoToLwError(pthread_mutex_init(&pEntry->lock, NULL)); BAIL_ON_ERROR(dwError); pEntry->pLock = &pEntry->lock; dwError = LwMapErrnoToLwError(pthread_cond_init(&pEntry->event, NULL)); BAIL_ON_ERROR(dwError); pEntry->pEvent = &pEntry->event; dwError = LwSmTableReconstructEntry(pEntry); BAIL_ON_ERROR(dwError); LOCK(bLocked, gServiceTable.pLock); LwSmLinkInsertBefore(&gServiceTable.entries, &pEntry->link); pEntry->dwRefCount++; UNLOCK(bLocked, gServiceTable.pLock); *ppEntry = pEntry; cleanup: return dwError; error: if (pEntry) { LwSmTableFreeEntry(pEntry); } goto cleanup; }
DWORD LwSmSrvGetServiceInfo( LW_SERVICE_HANDLE hHandle, PLW_SERVICE_INFO* ppInfo ) { DWORD dwError = 0; BOOLEAN bLocked = FALSE; LOCK(bLocked, hHandle->pEntry->pLock); dwError = LwSmCopyServiceInfo(hHandle->pEntry->pInfo, ppInfo); BAIL_ON_ERROR(dwError); error: UNLOCK(bLocked, hHandle->pEntry->pLock); return dwError; }
static DWORD LwSmTableGetEntryReverseDependencyClosureHelper( PSM_TABLE_ENTRY pEntry, PWSTR* ppwszAllServices, PWSTR** pppwszServiceList ) { DWORD dwError = 0; PLW_SERVICE_INFO pInfo = NULL; PLW_SERVICE_INFO pDepInfo = NULL; size_t i = 0; PSM_TABLE_ENTRY pDepEntry = NULL; PWSTR pwszDepName = NULL; BOOLEAN bLocked = FALSE; LOCK(bLocked, pEntry->pLock); dwError = LwSmCopyServiceInfo(pEntry->pInfo, &pInfo); UNLOCK(bLocked, pEntry->pLock); BAIL_ON_ERROR(dwError); for (i = 0; ppwszAllServices[i]; i++) { dwError = LwSmTableGetEntry(ppwszAllServices[i], &pDepEntry); BAIL_ON_ERROR(dwError); LOCK(bLocked, pEntry->pLock); dwError = LwSmCopyServiceInfo(pDepEntry->pInfo, &pDepInfo); UNLOCK(bLocked, pEntry->pLock); BAIL_ON_ERROR(dwError); if (LwSmStringListContains(pDepInfo->ppwszDependencies, pInfo->pwszName)) { dwError = LwSmTableGetEntryReverseDependencyClosureHelper( pDepEntry, ppwszAllServices, pppwszServiceList); BAIL_ON_ERROR(dwError); dwError = LwAllocateWc16String(&pwszDepName, pDepInfo->pwszName); BAIL_ON_ERROR(dwError); dwError = LwSmStringListAppend(pppwszServiceList, pwszDepName); BAIL_ON_ERROR(dwError); pwszDepName = NULL; } LwSmCommonFreeServiceInfo(pDepInfo); pDepInfo = NULL; LwSmTableReleaseEntry(pDepEntry); pDepEntry = NULL; } cleanup: LW_SAFE_FREE_MEMORY(pwszDepName); if (pInfo) { LwSmCommonFreeServiceInfo(pInfo); } if (pDepInfo) { LwSmCommonFreeServiceInfo(pDepInfo); } if (pDepEntry) { LwSmTableReleaseEntry(pDepEntry); } return dwError; error: goto cleanup; }