mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-27 16:15:23 +00:00
956953884e
Each thread can use a thread local variable to keep the name of a job which is currently running in the job. The virThreadJobSetWorker API is supposed to be called once by any thread which is used as a worker, i.e., it is waiting in a pool, woken up to do a job, and returned back to the pool. The virThreadJobSet/virThreadJobClear APIs are to be called at the beginning/end of each job. Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
127 lines
3.2 KiB
C
127 lines
3.2 KiB
C
/*
|
|
* virthreadjob.c: code for tracking job associated with current thread
|
|
*
|
|
* Copyright (C) 2013-2015 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Author: Jiri Denemark <jdenemar@redhat.com>
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include "internal.h"
|
|
#include "virerror.h"
|
|
#include "virlog.h"
|
|
#include "virthread.h"
|
|
#include "virthreadjob.h"
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_THREAD
|
|
VIR_LOG_INIT("util.threadjob");
|
|
|
|
virThreadLocal virThreadJobWorker;
|
|
virThreadLocal virThreadJobName;
|
|
|
|
|
|
static int
|
|
virThreadJobOnceInit(void)
|
|
{
|
|
if (virThreadLocalInit(&virThreadJobWorker, NULL) < 0 ||
|
|
virThreadLocalInit(&virThreadJobName, NULL) < 0)
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
VIR_ONCE_GLOBAL_INIT(virThreadJob)
|
|
|
|
|
|
const char *
|
|
virThreadJobGet(void)
|
|
{
|
|
const char *job;
|
|
|
|
if (virThreadJobInitialize() < 0)
|
|
return NULL;
|
|
|
|
job = virThreadLocalGet(&virThreadJobName);
|
|
if (!job)
|
|
job = virThreadLocalGet(&virThreadJobWorker);
|
|
|
|
return job;
|
|
}
|
|
|
|
|
|
void
|
|
virThreadJobSetWorker(const char *worker)
|
|
{
|
|
if (!worker || virThreadJobInitialize() < 0)
|
|
return;
|
|
|
|
if (virThreadLocalSet(&virThreadJobWorker, (void *) worker) < 0)
|
|
virReportSystemError(errno,
|
|
_("cannot set worker name to %s"),
|
|
worker);
|
|
|
|
VIR_DEBUG("Thread %llu is running worker %s", virThreadSelfID(), worker);
|
|
}
|
|
|
|
|
|
void
|
|
virThreadJobSet(const char *caller)
|
|
{
|
|
const char *worker;
|
|
|
|
if (!caller || virThreadJobInitialize() < 0)
|
|
return;
|
|
|
|
if (virThreadLocalSet(&virThreadJobName, (void *) caller) < 0)
|
|
virReportSystemError(errno,
|
|
_("cannot set current job to %s"),
|
|
caller);
|
|
|
|
if ((worker = virThreadLocalGet(&virThreadJobWorker))) {
|
|
VIR_DEBUG("Thread %llu (%s) is now running job %s",
|
|
virThreadSelfID(), worker, caller);
|
|
} else {
|
|
VIR_DEBUG("Thread %llu is now running job %s",
|
|
virThreadSelfID(), caller);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
virThreadJobClear(int rv)
|
|
{
|
|
const char *old;
|
|
const char *worker;
|
|
|
|
if (virThreadJobInitialize() < 0)
|
|
return;
|
|
|
|
if (!(old = virThreadLocalGet(&virThreadJobName)))
|
|
return;
|
|
|
|
if (virThreadLocalSet(&virThreadJobName, NULL) < 0)
|
|
virReportSystemError(errno, "%s", _("cannot reset current job"));
|
|
|
|
if ((worker = virThreadLocalGet(&virThreadJobWorker))) {
|
|
VIR_DEBUG("Thread %llu (%s) finished job %s with ret=%d",
|
|
virThreadSelfID(), worker, old, rv);
|
|
} else {
|
|
VIR_DEBUG("Thread %llu finished job %s with ret=%d",
|
|
virThreadSelfID(), old, rv);
|
|
}
|
|
}
|