virthreadpool: Allow setting identity for workers

In some cases the worker func running inside the pool may rely on
virIdentity. While worker func could check for identity and set
one it is not optimal - it may not have access to the identity of
the thread creating the pool and thus would have to call
virIdentityGetSystem(). Allow passing identity when creating the
pool.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Michal Privoznik 2021-10-26 11:04:24 +02:00
parent 775de86975
commit 0c8f1aeddf
5 changed files with 24 additions and 6 deletions

View File

@ -1333,6 +1333,7 @@ virNWFilterDHCPSnoopThread(void *req0)
worker = virThreadPoolNewFull(1, 1, 0,
virNWFilterDHCPDecodeWorker,
"dhcp-decode",
NULL,
req);
}

View File

@ -914,7 +914,9 @@ qemuStateInitialize(bool privileged,
* running domains since there might occur some QEMU monitor
* events that will be dispatched to the worker pool */
qemu_driver->workerPool = virThreadPoolNewFull(0, 1, 0, qemuProcessEventHandler,
"qemu-event", qemu_driver);
"qemu-event",
NULL,
qemu_driver);
if (!qemu_driver->workerPool)
goto error;

View File

@ -378,6 +378,7 @@ virNetServer *virNetServerNew(const char *name,
priority_workers,
virNetServerHandleJob,
"rpc-worker",
NULL,
srv)))
goto error;

View File

@ -55,6 +55,8 @@ struct _virThreadPool {
virThreadPoolJobList jobList;
size_t jobQueueDepth;
virIdentity *identity;
virMutex mutex;
virCond cond;
virCond quit_cond;
@ -99,6 +101,9 @@ static void virThreadPoolWorker(void *opaque)
virMutexLock(&pool->mutex);
if (pool->identity)
virIdentitySetCurrent(pool->identity);
while (1) {
/* In order to support async worker termination, we need ensure that
* both busy and free workers know if they need to terminated. Thus,
@ -219,6 +224,7 @@ virThreadPoolNewFull(size_t minWorkers,
size_t prioWorkers,
virThreadPoolJobFunc func,
const char *name,
virIdentity *identity,
void *opaque)
{
virThreadPool *pool;
@ -234,6 +240,9 @@ virThreadPoolNewFull(size_t minWorkers,
pool->jobName = name;
pool->jobOpaque = opaque;
if (identity)
pool->identity = g_object_ref(identity);
if (virMutexInit(&pool->mutex) < 0)
goto error;
if (virCondInit(&pool->cond) < 0)
@ -300,6 +309,9 @@ void virThreadPoolFree(virThreadPool *pool)
virMutexLock(&pool->mutex);
virThreadPoolDrainLocked(pool);
if (pool->identity)
g_object_unref(pool->identity);
g_free(pool->workers);
virMutexUnlock(&pool->mutex);
virMutexDestroy(&pool->mutex);

View File

@ -22,17 +22,19 @@
#pragma once
#include "internal.h"
#include "viridentity.h"
typedef struct _virThreadPool virThreadPool;
typedef void (*virThreadPoolJobFunc)(void *jobdata, void *opaque);
virThreadPool *virThreadPoolNewFull(size_t minWorkers,
size_t maxWorkers,
size_t prioWorkers,
virThreadPoolJobFunc func,
const char *name,
void *opaque) ATTRIBUTE_NONNULL(4);
size_t maxWorkers,
size_t prioWorkers,
virThreadPoolJobFunc func,
const char *name,
virIdentity *identity,
void *opaque) ATTRIBUTE_NONNULL(4);
size_t virThreadPoolGetMinWorkers(virThreadPool *pool);
size_t virThreadPoolGetMaxWorkers(virThreadPool *pool);