Exemple #1
0
/**
 * virUnrefSecret:
 * @secret: the secret to unreference
 *
 * Unreference the secret. If the use count drops to zero, the structure is
 * actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
virUnrefSecret(virSecretPtr secret) {
    int refs;

    if (!VIR_IS_CONNECTED_SECRET(secret)) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("bad secret or no connection"));
        return -1;
    }
    virMutexLock(&secret->conn->lock);
    VIR_DEBUG("unref secret %p %p %d", secret, secret->uuid, secret->refs);
    secret->refs--;
    refs = secret->refs;
    if (refs == 0) {
        virReleaseSecret(secret);
        /* Already unlocked mutex */
        return 0;
    }

    virMutexUnlock(&secret->conn->lock);
    return refs;
}
Exemple #2
0
/**
 * virReleaseStorageVol:
 * @vol: the vol to release
 *
 * Unconditionally release all memory associated with a vol.
 * The conn.lock mutex must be held prior to calling this, and will
 * be released prior to this returning. The vol obj must not
 * be used once this method returns.
 *
 * It will also unreference the associated connection object,
 * which may also be released if its ref count hits zero.
 */
static void
virReleaseStorageVol(virStorageVolPtr vol) {
    virConnectPtr conn = vol->conn;
    VIR_DEBUG("release vol %p %s", vol, vol->name);

    vol->magic = -1;
    VIR_FREE(vol->name);
    VIR_FREE(vol->pool);
    VIR_FREE(vol);

    if (conn) {
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
    }
}
Exemple #3
0
/**
 * virReleaseNodeDevice:
 * @dev: the dev to release
 *
 * Unconditionally release all memory associated with a dev.
 * The conn.lock mutex must be held prior to calling this, and will
 * be released prior to this returning. The dev obj must not
 * be used once this method returns.
 *
 * It will also unreference the associated connection object,
 * which may also be released if its ref count hits zero.
 */
static void
virReleaseNodeDevice(virNodeDevicePtr dev) {
    virConnectPtr conn = dev->conn;
    VIR_DEBUG("release dev %p %s", dev, dev->name);

    dev->magic = -1;
    VIR_FREE(dev->name);
    VIR_FREE(dev->parent);
    VIR_FREE(dev);

    if (conn) {
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
    }
}
Exemple #4
0
/**
 * virReleaseInterface:
 * @interface: the interface to release
 *
 * Unconditionally release all memory associated with an interface.
 * The conn.lock mutex must be held prior to calling this, and will
 * be released prior to this returning. The interface obj must not
 * be used once this method returns.
 *
 * It will also unreference the associated connection object,
 * which may also be released if its ref count hits zero.
 */
static void
virReleaseInterface(virInterfacePtr iface) {
    virConnectPtr conn = iface->conn;
    VIR_DEBUG("release interface %p %s", iface, iface->name);

    iface->magic = -1;
    VIR_FREE(iface->name);
    VIR_FREE(iface->mac);
    VIR_FREE(iface);

    if (conn) {
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
    }
}
Exemple #5
0
/**
 * virUnrefDomain:
 * @domain: the domain to unreference
 *
 * Unreference the domain. If the use count drops to zero, the structure is
 * actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
virUnrefDomain(virDomainPtr domain) {
    int refs;

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("bad domain or no connection"));
        return -1;
    }
    virMutexLock(&domain->conn->lock);
    VIR_DEBUG("unref domain %p %s %d", domain, domain->name, domain->refs);
    domain->refs--;
    refs = domain->refs;
    if (refs == 0) {
        virReleaseDomain(domain);
        /* Already unlocked mutex */
        return (0);
    }

    virMutexUnlock(&domain->conn->lock);
    return (refs);
}
Exemple #6
0
static void
virReleaseDomainSnapshot(virDomainSnapshotPtr snapshot)
{
    virDomainPtr domain = snapshot->domain;
    VIR_DEBUG("release snapshot %p %s", snapshot, snapshot->name);

    snapshot->magic = -1;
    VIR_FREE(snapshot->name);
    VIR_FREE(snapshot);

    if (domain) {
        VIR_DEBUG("unref domain %p %d", domain, domain->refs);
        domain->refs--;
        if (domain->refs == 0) {
            virReleaseDomain(domain);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&domain->conn->lock);
    }
}
Exemple #7
0
/* Iterate over all file handles and dispatch any which
 * have pending events listed in the poll() data. Invoke
 * the user supplied callback for each handle which has
 * pending events
 *
 * This method must cope with new handles being registered
 * by a callback, and must skip any handles marked as deleted.
 *
 * Returns 0 upon success, -1 if an error occurred
 */
static int virEventPollDispatchHandles(int nfds, struct pollfd *fds)
{
    size_t i, n;
    VIR_DEBUG("Dispatch %d", nfds);

    /* NB, use nfds not eventLoop.handlesCount, because new
     * fds might be added on end of list, and they're not
     * in the fds array we've got */
    for (i = 0, n = 0; n < nfds && i < eventLoop.handlesCount; n++) {
        while (i < eventLoop.handlesCount &&
               (eventLoop.handles[i].fd != fds[n].fd ||
                eventLoop.handles[i].events == 0)) {
            i++;
        }
        if (i == eventLoop.handlesCount)
            break;

        VIR_DEBUG("i=%zu w=%d", i, eventLoop.handles[i].watch);
        if (eventLoop.handles[i].deleted) {
            EVENT_DEBUG("Skip deleted n=%zu w=%d f=%d", i,
                        eventLoop.handles[i].watch, eventLoop.handles[i].fd);
            continue;
        }

        if (fds[n].revents) {
            virEventHandleCallback cb = eventLoop.handles[i].cb;
            int watch = eventLoop.handles[i].watch;
            void *opaque = eventLoop.handles[i].opaque;
            int hEvents = virEventPollFromNativeEvents(fds[n].revents);
            PROBE(EVENT_POLL_DISPATCH_HANDLE,
                  "watch=%d events=%d",
                  watch, hEvents);
            virMutexUnlock(&eventLoop.lock);
            (cb)(watch, fds[n].fd, hEvents, opaque);
            virMutexLock(&eventLoop.lock);
        }
    }

    return 0;
}
Exemple #8
0
/*
 * @client: a locked client to add the stream to
 * @stream: a stream to add
 */
int daemonAddClientStream(virNetServerClientPtr client,
                          daemonClientStream *stream,
                          bool transmit)
{
    VIR_DEBUG("client=%p, proc=%d, serial=%d, st=%p, transmit=%d",
              client, stream->procedure, stream->serial, stream->st, transmit);
    daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);

    if (stream->filterID != -1) {
        VIR_WARN("Filter already added to client %p", client);
        return -1;
    }

    if (virStreamEventAddCallback(stream->st, 0,
                                  daemonStreamEvent, client,
                                  virObjectFreeCallback) < 0)
        return -1;

    virObjectRef(client);

    if ((stream->filterID = virNetServerClientAddFilter(client,
                                                        daemonStreamFilter,
                                                        stream)) < 0) {
        virStreamEventRemoveCallback(stream->st);
        return -1;
    }

    if (transmit)
        stream->tx = 1;

    virMutexLock(&priv->lock);
    stream->next = priv->streams;
    priv->streams = stream;

    daemonStreamUpdateEvents(stream);

    virMutexUnlock(&priv->lock);

    return 0;
}
Exemple #9
0
void virEventPollUpdateHandle(int watch, int events) {
    int i;
    PROBE(EVENT_POLL_UPDATE_HANDLE,
          "watch=%d events=%d",
          watch, events);

    if (watch <= 0) {
        VIR_WARN("Ignoring invalid update watch %d", watch);
        return;
    }

    virMutexLock(&eventLoop.lock);
    for (i = 0 ; i < eventLoop.handlesCount ; i++) {
        if (eventLoop.handles[i].watch == watch) {
            eventLoop.handles[i].events =
                    virEventPollToNativeEvents(events);
            virEventPollInterruptLocked();
            break;
        }
    }
    virMutexUnlock(&eventLoop.lock);
}
Exemple #10
0
int virNetClientStreamQueuePacket(virNetClientStreamPtr st,
                                  virNetMessagePtr msg)
{
    int ret = -1;
    size_t need;

    virMutexLock(&st->lock);
    need = msg->bufferLength - msg->bufferOffset;
    if (need) {
        size_t avail = st->incomingLength - st->incomingOffset;
        if (need > avail) {
            size_t extra = need - avail;
            if (VIR_REALLOC_N(st->incoming,
                              st->incomingLength + extra) < 0) {
                VIR_DEBUG("Out of memory handling stream data");
                goto cleanup;
            }
            st->incomingLength += extra;
        }

        memcpy(st->incoming + st->incomingOffset,
               msg->buffer + msg->bufferOffset,
               msg->bufferLength - msg->bufferOffset);
        st->incomingOffset += (msg->bufferLength - msg->bufferOffset);
    } else {
        st->incomingEOF = true;
    }

    VIR_DEBUG("Stream incoming data offset %zu length %zu EOF %d",
              st->incomingOffset, st->incomingLength,
              st->incomingEOF);
    virNetClientStreamEventTimerUpdate(st);

    ret = 0;

cleanup:
    virMutexUnlock(&st->lock);
    return ret;
}
Exemple #11
0
/**
 * virUnrefInterface:
 * @interface: the interface to unreference
 *
 * Unreference the interface. If the use count drops to zero, the structure is
 * actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
virUnrefInterface(virInterfacePtr iface) {
    int refs;

    if (!VIR_IS_CONNECTED_INTERFACE(iface)) {
        virLibConnError(VIR_ERR_INVALID_INTERFACE,
                        _("bad interface or no connection"));
        return -1;
    }
    virMutexLock(&iface->conn->lock);
    VIR_DEBUG("unref interface %p %s %d", iface, iface->name, iface->refs);
    iface->refs--;
    refs = iface->refs;
    if (refs == 0) {
        virReleaseInterface(iface);
        /* Already unlocked mutex */
        return 0;
    }

    virMutexUnlock(&iface->conn->lock);
    return refs;
}
Exemple #12
0
/**
 * virUnrefStoragePool:
 * @pool: the pool to unreference
 *
 * Unreference the pool. If the use count drops to zero, the structure is
 * actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
virUnrefStoragePool(virStoragePoolPtr pool) {
    int refs;

    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
        virLibConnError(VIR_ERR_INVALID_STORAGE_POOL,
                        _("bad storage pool or no connection"));
        return -1;
    }
    virMutexLock(&pool->conn->lock);
    VIR_DEBUG("unref pool %p %s %d", pool, pool->name, pool->refs);
    pool->refs--;
    refs = pool->refs;
    if (refs == 0) {
        virReleaseStoragePool(pool);
        /* Already unlocked mutex */
        return 0;
    }

    virMutexUnlock(&pool->conn->lock);
    return refs;
}
Exemple #13
0
int virNetClientStreamEventUpdateCallback(virNetClientStreamPtr st,
                                          int events)
{
    int ret = -1;

    virMutexLock(&st->lock);
    if (!st->cb) {
        virNetError(VIR_ERR_INTERNAL_ERROR,
                    "%s", _("no stream callback registered"));
        goto cleanup;
    }

    st->cbEvents = events;

    virNetClientStreamEventTimerUpdate(st);

    ret = 0;

cleanup:
    virMutexUnlock(&st->lock);
    return ret;
}
Exemple #14
0
/**
 * virUnrefStorageVol:
 * @vol: the vol to unreference
 *
 * Unreference the vol. If the use count drops to zero, the structure is
 * actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
virUnrefStorageVol(virStorageVolPtr vol) {
    int refs;

    if (!VIR_IS_CONNECTED_STORAGE_VOL(vol)) {
        virLibConnError(VIR_ERR_INVALID_STORAGE_VOL,
                        _("bad storage volume or no connection"));
        return -1;
    }
    virMutexLock(&vol->conn->lock);
    VIR_DEBUG("unref vol %p %s %d", vol, vol->name, vol->refs);
    vol->refs--;
    refs = vol->refs;
    if (refs == 0) {
        virReleaseStorageVol(vol);
        /* Already unlocked mutex */
        return 0;
    }

    virMutexUnlock(&vol->conn->lock);
    return refs;
}
Exemple #15
0
int virThreadLocalInit(virThreadLocalPtr l,
                       virThreadLocalCleanup c)
{
    if ((l->key = TlsAlloc()) == TLS_OUT_OF_INDEXES) {
        errno = ESRCH;
        return -1;
    }
    TlsSetValue(l->key, NULL);

    if (c) {
        virMutexLock(&virThreadLocalLock);
        if (VIR_REALLOC_N(virThreadLocalList,
                          virThreadLocalCount + 1) < 0)
            return -1;
        virThreadLocalList[virThreadLocalCount].key = l->key;
        virThreadLocalList[virThreadLocalCount].cleanup = c;
        virThreadLocalCount++;
        virMutexUnlock(&virThreadLocalLock);
    }

    return 0;
}
Exemple #16
0
/**
 * virUnrefNetwork:
 * @network: the network to unreference
 *
 * Unreference the network. If the use count drops to zero, the structure is
 * actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
virUnrefNetwork(virNetworkPtr network) {
    int refs;

    if (!VIR_IS_CONNECTED_NETWORK(network)) {
        virLibConnError(VIR_ERR_INVALID_NETWORK,
                        _("bad network or no connection"));
        return -1;
    }
    virMutexLock(&network->conn->lock);
    VIR_DEBUG("unref network %p %s %d", network, network->name, network->refs);
    network->refs--;
    refs = network->refs;
    if (refs == 0) {
        virReleaseNetwork(network);
        /* Already unlocked mutex */
        return 0;
    }

    virMutexUnlock(&network->conn->lock);
    return refs;
}
Exemple #17
0
int virNetClientStreamEventAddCallback(virNetClientStreamPtr st,
                                       int events,
                                       virNetClientStreamEventCallback cb,
                                       void *opaque,
                                       virFreeCallback ff)
{
    int ret = -1;

    virMutexLock(&st->lock);
    if (st->cb) {
        virNetError(VIR_ERR_INTERNAL_ERROR,
                    "%s", _("multiple stream callbacks not supported"));
        goto cleanup;
    }

    st->refs++;
    if ((st->cbTimer =
         virEventAddTimeout(-1,
                            virNetClientStreamEventTimer,
                            st,
                            virNetClientStreamEventTimerFree)) < 0) {
        st->refs--;
        goto cleanup;
    }

    st->cb = cb;
    st->cbOpaque = opaque;
    st->cbFree = ff;
    st->cbEvents = events;

    virNetClientStreamEventTimerUpdate(st);

    ret = 0;

cleanup:
    virMutexUnlock(&st->lock);
    return ret;
}
ssize_t virNetSASLSessionEncode(virNetSASLSessionPtr sasl,
                                const char *input,
                                size_t inputLen,
                                const char **output,
                                size_t *outputlen)
{
    unsigned inlen = inputLen;
    unsigned outlen = 0;
    int err;
    ssize_t ret = -1;

    virMutexLock(&sasl->lock);
    if (inputLen > sasl->maxbufsize) {
        virReportSystemError(EINVAL,
                             _("SASL data length %zu too long, max %zu"),
                             inputLen, sasl->maxbufsize);
        goto cleanup;
    }

    err = sasl_encode(sasl->conn,
                      input,
                      inlen,
                      output,
                      &outlen);
    *outputlen = outlen;

    if (err != SASL_OK) {
        virNetError(VIR_ERR_INTERNAL_ERROR,
                    _("failed to encode SASL data: %d (%s)"),
                    err, sasl_errstring(err, NULL, NULL));
        goto cleanup;
    }
    ret = 0;

cleanup:
    virMutexUnlock(&sasl->lock);
    return ret;
}
Exemple #19
0
int
virUnrefDomainSnapshot(virDomainSnapshotPtr snapshot)
{
    int refs;

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
        virLibConnError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT, _("not a snapshot"));
        return -1;
    }

    virMutexLock(&snapshot->domain->conn->lock);
    VIR_DEBUG("unref snapshot %p %s %d", snapshot, snapshot->name, snapshot->refs);
    snapshot->refs--;
    refs = snapshot->refs;
    if (refs == 0) {
        virReleaseDomainSnapshot(snapshot);
        /* Already unlocked mutex */
        return 0;
    }

    virMutexUnlock(&snapshot->domain->conn->lock);
    return refs;
}
Exemple #20
0
/**
 * virReleaseSecret:
 * @secret: the secret to release
 *
 * Unconditionally release all memory associated with a secret.  The conn.lock
 * mutex must be held prior to calling this, and will be released prior to this
 * returning. The secret obj must not be used once this method returns.
 *
 * It will also unreference the associated connection object, which may also be
 * released if its ref count hits zero.
 */
static void
virReleaseSecret(virSecretPtr secret) {
    virConnectPtr conn = secret->conn;
    char uuidstr[VIR_UUID_STRING_BUFLEN];

    virUUIDFormat(secret->uuid, uuidstr);
    VIR_DEBUG("release secret %p %s", secret, uuidstr);

    VIR_FREE(secret->usageID);
    secret->magic = -1;
    VIR_FREE(secret);

    if (conn) {
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
    }
}
Exemple #21
0
/**
 * virReleaseNetwork:
 * @network: the network to release
 *
 * Unconditionally release all memory associated with a network.
 * The conn.lock mutex must be held prior to calling this, and will
 * be released prior to this returning. The network obj must not
 * be used once this method returns.
 *
 * It will also unreference the associated connection object,
 * which may also be released if its ref count hits zero.
 */
static void
virReleaseNetwork(virNetworkPtr network) {
    virConnectPtr conn = network->conn;
    char uuidstr[VIR_UUID_STRING_BUFLEN];

    virUUIDFormat(network->uuid, uuidstr);
    VIR_DEBUG("release network %p %s %s", network, network->name, uuidstr);

    network->magic = -1;
    VIR_FREE(network->name);
    VIR_FREE(network);

    if (conn) {
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
    }
}
Exemple #22
0
/**
 * virReleaseStoragePool:
 * @pool: the pool to release
 *
 * Unconditionally release all memory associated with a pool.
 * The conn.lock mutex must be held prior to calling this, and will
 * be released prior to this returning. The pool obj must not
 * be used once this method returns.
 *
 * It will also unreference the associated connection object,
 * which may also be released if its ref count hits zero.
 */
static void
virReleaseStoragePool(virStoragePoolPtr pool) {
    virConnectPtr conn = pool->conn;
    char uuidstr[VIR_UUID_STRING_BUFLEN];

    virUUIDFormat(pool->uuid, uuidstr);
    VIR_DEBUG("release pool %p %s %s", pool, pool->name, uuidstr);

    pool->magic = -1;
    VIR_FREE(pool->name);
    VIR_FREE(pool);

    if (conn) {
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
    }
}
Exemple #23
0
/**
 * virConnectDispose:
 * @conn: the hypervisor connection to release
 *
 * Unconditionally release all memory associated with a connection.
 * The conn.lock mutex must be held prior to calling this, and will
 * be released prior to this returning. The connection obj must not
 * be used once this method returns.
 */
static void
virConnectDispose(void *obj)
{
    virConnectPtr conn = obj;

    if (conn->networkDriver)
        conn->networkDriver->networkClose(conn);
    if (conn->interfaceDriver)
        conn->interfaceDriver->interfaceClose(conn);
    if (conn->storageDriver)
        conn->storageDriver->storageClose(conn);
    if (conn->nodeDeviceDriver)
        conn->nodeDeviceDriver->nodeDeviceClose(conn);
    if (conn->secretDriver)
        conn->secretDriver->secretClose(conn);
    if (conn->nwfilterDriver)
        conn->nwfilterDriver->nwfilterClose(conn);
    if (conn->driver)
        conn->driver->connectClose(conn);

    virMutexLock(&conn->lock);

    virResetError(&conn->err);

    virURIFree(conn->uri);

    if (conn->closeCallback) {
        virObjectLock(conn->closeCallback);
        conn->closeCallback->callback = NULL;
        virObjectUnlock(conn->closeCallback);

        virObjectUnref(conn->closeCallback);
    }

    virMutexUnlock(&conn->lock);
    virMutexDestroy(&conn->lock);
}
Exemple #24
0
/*
 * Iterate over all timers and determine if any have expired.
 * Invoke the user supplied callback for each timer whose
 * expiry time is met, and schedule the next timeout. Does
 * not try to 'catch up' on time if the actual expiry time
 * was later than the requested time.
 *
 * This method must cope with new timers being registered
 * by a callback, and must skip any timers marked as deleted.
 *
 * Returns 0 upon success, -1 if an error occurred
 */
static int virEventPollDispatchTimeouts(void)
{
    unsigned long long now;
    int i;
    /* Save this now - it may be changed during dispatch */
    int ntimeouts = eventLoop.timeoutsCount;
    VIR_DEBUG("Dispatch %d", ntimeouts);

    if (virTimeMillisNow(&now) < 0)
        return -1;

    for (i = 0 ; i < ntimeouts ; i++) {
        if (eventLoop.timeouts[i].deleted || eventLoop.timeouts[i].frequency < 0)
            continue;

        /* Add 20ms fuzz so we don't pointlessly spin doing
         * <10ms sleeps, particularly on kernels with low HZ
         * it is fine that a timer expires 20ms earlier than
         * requested
         */
        if (eventLoop.timeouts[i].expiresAt <= (now+20)) {
            virEventTimeoutCallback cb = eventLoop.timeouts[i].cb;
            int timer = eventLoop.timeouts[i].timer;
            void *opaque = eventLoop.timeouts[i].opaque;
            eventLoop.timeouts[i].expiresAt =
                now + eventLoop.timeouts[i].frequency;

            PROBE(EVENT_POLL_DISPATCH_TIMEOUT,
                  "timer=%d",
                  timer);
            virMutexUnlock(&eventLoop.lock);
            (cb)(timer, opaque);
            virMutexLock(&eventLoop.lock);
        }
    }
    return 0;
}
static int virFDStreamRemoveCallback(virStreamPtr stream)
{
    struct virFDStreamData *fdst = stream->privateData;
    int ret = -1;

    if (!fdst) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("stream is not open"));
        return -1;
    }

    virMutexLock(&fdst->lock);
    if (fdst->watch == 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("stream does not have a callback registered"));
        goto cleanup;
    }

    virEventRemoveHandle(fdst->watch);
    if (fdst->dispatching)
        fdst->cbRemoved = true;
    else if (fdst->ff)
        (fdst->ff)(fdst->opaque);

    fdst->watch = 0;
    fdst->ff = NULL;
    fdst->cb = NULL;
    fdst->events = 0;
    fdst->opaque = NULL;

    ret = 0;

 cleanup:
    virMutexUnlock(&fdst->lock);
    return ret;
}
Exemple #26
0
/**
 * virUnrefNWFilter:
 * @nwfilter: the nwfilter to unreference
 *
 * Unreference the networkf itler. If the use count drops to zero, the
 * structure is actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
virUnrefNWFilter(virNWFilterPtr nwfilter)
{
    int refs;

    if (!VIR_IS_CONNECTED_NWFILTER(nwfilter)) {
        virLibConnError(VIR_ERR_INVALID_NWFILTER,
                        _("bad nwfilter or no connection"));
        return -1;
    }
    virMutexLock(&nwfilter->conn->lock);
    VIR_DEBUG("unref nwfilter %p %s %d", nwfilter, nwfilter->name,
              nwfilter->refs);
    nwfilter->refs--;
    refs = nwfilter->refs;
    if (refs == 0) {
        virReleaseNWFilter(nwfilter);
        /* Already unlocked mutex */
        return 0;
    }

    virMutexUnlock(&nwfilter->conn->lock);
    return refs;
}
Exemple #27
0
/**
 * virReleaseDomain:
 * @domain: the domain to release
 *
 * Unconditionally release all memory associated with a domain.
 * The conn.lock mutex must be held prior to calling this, and will
 * be released prior to this returning. The domain obj must not
 * be used once this method returns.
 *
 * It will also unreference the associated connection object,
 * which may also be released if its ref count hits zero.
 */
static void
virReleaseDomain(virDomainPtr domain) {
    virConnectPtr conn = domain->conn;
    char uuidstr[VIR_UUID_STRING_BUFLEN];

    virUUIDFormat(domain->uuid, uuidstr);
    VIR_DEBUG("release domain %p %s %s", domain, domain->name, uuidstr);

    domain->magic = -1;
    domain->id = -1;
    VIR_FREE(domain->name);
    VIR_FREE(domain);

    if (conn) {
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
    }
}
Exemple #28
0
void virEventPollUpdateTimeout(int timer, int frequency)
{
    unsigned long long now;
    int i;
    bool found = false;
    PROBE(EVENT_POLL_UPDATE_TIMEOUT,
          "timer=%d frequency=%d",
          timer, frequency);

    if (timer <= 0) {
        VIR_WARN("Ignoring invalid update timer %d", timer);
        return;
    }

    if (virTimeMillisNow(&now) < 0) {
        return;
    }

    virMutexLock(&eventLoop.lock);
    for (i = 0; i < eventLoop.timeoutsCount; i++) {
        if (eventLoop.timeouts[i].timer == timer) {
            eventLoop.timeouts[i].frequency = frequency;
            eventLoop.timeouts[i].expiresAt =
                frequency >= 0 ? frequency + now : 0;
            VIR_DEBUG("Set timer freq=%d expires=%llu", frequency,
                      eventLoop.timeouts[i].expiresAt);
            virEventPollInterruptLocked();
            found = true;
            break;
        }
    }
    virMutexUnlock(&eventLoop.lock);

    if (!found)
        VIR_WARN("Got update for non-existent timer %d", timer);
}
Exemple #29
0
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);
}
Exemple #30
0
/**
 * virObjectEventStateUnlock:
 * @state: the event state object
 *
 * Unlock event state after calling functions from object_event_private.h.
 */
static void
virObjectEventStateUnlock(virObjectEventStatePtr state)
{
    virMutexUnlock(&state->lock);
}