int virThreadPoolSetParameters(virThreadPoolPtr pool, long long int minWorkers, long long int maxWorkers, long long int prioWorkers) { size_t max; size_t min; virMutexLock(&pool->mutex); max = maxWorkers >= 0 ? maxWorkers : pool->maxWorkers; min = minWorkers >= 0 ? minWorkers : pool->minWorkers; if (min > max) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("minWorkers cannot be larger than maxWorkers")); goto error; } if (minWorkers >= 0) { if ((size_t) minWorkers > pool->nWorkers && virThreadPoolExpand(pool, minWorkers - pool->nWorkers, false) < 0) goto error; pool->minWorkers = minWorkers; } if (maxWorkers >= 0) { pool->maxWorkers = maxWorkers; virCondBroadcast(&pool->cond); } if (prioWorkers >= 0) { if (prioWorkers < pool->nPrioWorkers) { virCondBroadcast(&pool->prioCond); } else if ((size_t) prioWorkers > pool->nPrioWorkers && virThreadPoolExpand(pool, prioWorkers - pool->nPrioWorkers, true) < 0) { goto error; } pool->maxPrioWorkers = prioWorkers; } virMutexUnlock(&pool->mutex); return 0; error: virMutexUnlock(&pool->mutex); return -1; }
void virThreadPoolFree(virThreadPoolPtr pool) { virThreadPoolJobPtr job; bool priority = false; if (!pool) return; virMutexLock(&pool->mutex); pool->quit = true; if (pool->nWorkers > 0) virCondBroadcast(&pool->cond); if (pool->nPrioWorkers > 0) { priority = true; virCondBroadcast(&pool->prioCond); } while (pool->nWorkers > 0 || pool->nPrioWorkers > 0) ignore_value(virCondWait(&pool->quit_cond, &pool->mutex)); while ((job = pool->jobList.head)) { pool->jobList.head = pool->jobList.head->next; VIR_FREE(job); } VIR_FREE(pool->workers); virMutexUnlock(&pool->mutex); virMutexDestroy(&pool->mutex); virCondDestroy(&pool->quit_cond); virCondDestroy(&pool->cond); if (priority) { VIR_FREE(pool->prioWorkers); virCondDestroy(&pool->prioCond); } VIR_FREE(pool); }
/* This method processes data that has been received * from the monitor. Looking for async events and * replies/errors. */ static int qemuAgentIOProcess(qemuAgentPtr mon) { int len; qemuAgentMessagePtr msg = NULL; /* See if there's a message ready for reply; that is, * one that has completed writing all its data. */ if (mon->msg && mon->msg->txOffset == mon->msg->txLength) msg = mon->msg; #if DEBUG_IO # if DEBUG_RAW_IO char *str1 = qemuAgentEscapeNonPrintable(msg ? msg->txBuffer : ""); char *str2 = qemuAgentEscapeNonPrintable(mon->buffer); VIR_ERROR(_("Process %zu %p %p [[[%s]]][[[%s]]]"), mon->bufferOffset, mon->msg, msg, str1, str2); VIR_FREE(str1); VIR_FREE(str2); # else VIR_DEBUG("Process %zu", mon->bufferOffset); # endif #endif len = qemuAgentIOProcessData(mon, mon->buffer, mon->bufferOffset, msg); if (len < 0) return -1; if (len < mon->bufferOffset) { memmove(mon->buffer, mon->buffer + len, mon->bufferOffset - len); mon->bufferOffset -= len; } else { VIR_FREE(mon->buffer); mon->bufferOffset = mon->bufferLength = 0; } #if DEBUG_IO VIR_DEBUG("Process done %zu used %d", mon->bufferOffset, len); #endif if (msg && msg->finished) virCondBroadcast(&mon->notify); return len; }