Esempio n. 1
0
/**
 * virObjectEventStateCallbackID:
 * @conn: connection associated with callback
 * @state: object event state
 * @klass: the base event class
 * @eventID: the event ID
 * @callback: function registered as a callback
 *
 * Returns the callbackID of @callback, or -1 with an error issued if the
 * function is not currently registered.  This only finds functions
 * registered via virConnectDomainEventRegister, even if modern style
 * virConnectDomainEventRegisterAny also registers the same callback.
 */
int
virObjectEventStateCallbackID(virConnectPtr conn,
                              virObjectEventStatePtr state,
                              virClassPtr klass,
                              int eventID,
                              virConnectObjectEventGenericCallback callback)
{
    int ret = -1;

    virObjectEventStateLock(state);
    ret = virObjectEventCallbackLookup(conn, state->callbacks, NULL,
                                       klass, eventID, callback, true, NULL);
    virObjectEventStateUnlock(state);

    if (ret < 0)
        virReportError(VIR_ERR_INVALID_ARG,
                       _("event callback function %p not registered"),
                       callback);
    return ret;
}
Esempio n. 2
0
/**
 * virObjectEventCallbackListAddID:
 * @conn: pointer to the connection
 * @cbList: the list
 * @uuid: the optional uuid of the object to filter on
 * @filter: optional last-ditch filter callback
 * @filter_opaque: opaque data to pass to @filter
 * @klass: the base event class
 * @eventID: the event ID
 * @callback: the callback to add
 * @opaque: opaque data to pass to @callback
 * @freecb: callback to free @opaque
 * @legacy: true if callback is tracked by function instead of callbackID
 * @callbackID: filled with callback ID
 * @serverFilter: true if server supports object filtering
 *
 * Internal function to add a callback from a virObjectEventCallbackListPtr
 */
static int
virObjectEventCallbackListAddID(virConnectPtr conn,
                                virObjectEventCallbackListPtr cbList,
                                unsigned char uuid[VIR_UUID_BUFLEN],
                                virObjectEventCallbackFilter filter,
                                void *filter_opaque,
                                virClassPtr klass,
                                int eventID,
                                virConnectObjectEventGenericCallback callback,
                                void *opaque,
                                virFreeCallback freecb,
                                bool legacy,
                                int *callbackID,
                                bool serverFilter)
{
    virObjectEventCallbackPtr event;
    int ret = -1;
    int remoteID = -1;

    VIR_DEBUG("conn=%p cblist=%p uuid=%p filter=%p filter_opaque=%p "
              "klass=%p eventID=%d callback=%p opaque=%p "
              "legacy=%d callbackID=%p serverFilter=%d",
              conn, cbList, uuid, filter, filter_opaque, klass, eventID,
              callback, opaque, legacy, callbackID, serverFilter);

    /* Check incoming */
    if (!cbList)
        return -1;

    /* If there is no additional filtering, then check if we already
     * have this callback on our list.  */
    if (!filter &&
        virObjectEventCallbackLookup(conn, cbList, uuid,
                                     klass, eventID, callback, legacy,
                                     serverFilter ? &remoteID : NULL) != -1) {
        virReportError(VIR_ERR_INVALID_ARG, "%s",
                       _("event callback already tracked"));
        return -1;
    }
    /* Allocate new event */
    if (VIR_ALLOC(event) < 0)
        goto cleanup;
    event->conn = virObjectRef(conn);
    *callbackID = event->callbackID = cbList->nextID++;
    event->cb = callback;
    event->klass = klass;
    event->eventID = eventID;
    event->opaque = opaque;
    event->freecb = freecb;
    event->remoteID = remoteID;

    /* Only need 'uuid' for matching; 'id' can change as domain
     * switches between running and shutoff, and 'name' can change in
     * Xen migration.  */
    if (uuid) {
        event->uuid_filter = true;
        memcpy(event->uuid, uuid, VIR_UUID_BUFLEN);
    }
    event->filter = filter;
    event->filter_opaque = filter_opaque;
    event->legacy = legacy;

    if (VIR_APPEND_ELEMENT(cbList->callbacks, cbList->count, event) < 0)
        goto cleanup;

    /* When additional filtering is being done, every client callback
     * is matched to exactly one server callback.  */
    if (filter) {
        ret = 1;
    } else {
        ret = virObjectEventCallbackListCount(conn, cbList, klass, eventID,
                                              uuid, serverFilter);
        if (serverFilter && remoteID < 0)
            ret++;
    }

 cleanup:
    if (event)
        virObjectUnref(event->conn);
    VIR_FREE(event);
    return ret;
}
Esempio n. 3
0
/**
 * virObjectEventCallbackListAddID:
 * @conn: pointer to the connection
 * @cbList: the list
 * @key: the optional key of the object to filter on
 * @filter: optional last-ditch filter callback
 * @filter_opaque: opaque data to pass to @filter
 * @klass: the base event class
 * @eventID: the event ID
 * @callback: the callback to add
 * @opaque: opaque data to pass to @callback
 * @freecb: callback to free @opaque
 * @legacy: true if callback is tracked by function instead of callbackID
 * @callbackID: filled with callback ID
 * @serverFilter: true if server supports object filtering
 *
 * Internal function to add a callback from a virObjectEventCallbackListPtr
 */
static int
virObjectEventCallbackListAddID(virConnectPtr conn,
                                virObjectEventCallbackListPtr cbList,
                                const char *key,
                                virObjectEventCallbackFilter filter,
                                void *filter_opaque,
                                virClassPtr klass,
                                int eventID,
                                virConnectObjectEventGenericCallback callback,
                                void *opaque,
                                virFreeCallback freecb,
                                bool legacy,
                                int *callbackID,
                                bool serverFilter)
{
    virObjectEventCallbackPtr cb;
    int ret = -1;
    int remoteID = -1;

    VIR_DEBUG("conn=%p cblist=%p key=%p filter=%p filter_opaque=%p "
              "klass=%p eventID=%d callback=%p opaque=%p "
              "legacy=%d callbackID=%p serverFilter=%d",
              conn, cbList, key, filter, filter_opaque, klass, eventID,
              callback, opaque, legacy, callbackID, serverFilter);

    /* Check incoming */
    if (!cbList)
        return -1;

    /* If there is no additional filtering, then check if we already
     * have this callback on our list.  */
    if (!filter &&
        virObjectEventCallbackLookup(conn, cbList, key,
                                     klass, eventID, callback, legacy,
                                     serverFilter ? &remoteID : NULL) != -1) {
        virReportError(VIR_ERR_INVALID_ARG, "%s",
                       _("event callback already tracked"));
        return -1;
    }
    /* Allocate new cb */
    if (VIR_ALLOC(cb) < 0)
        goto cleanup;
    cb->conn = virObjectRef(conn);
    *callbackID = cb->callbackID = cbList->nextID++;
    cb->cb = callback;
    cb->klass = klass;
    cb->eventID = eventID;
    cb->opaque = opaque;
    cb->freecb = freecb;
    cb->remoteID = remoteID;

    if (key) {
        cb->key_filter = true;
        if (VIR_STRDUP(cb->key, key) < 0)
            goto cleanup;
    }
    cb->filter = filter;
    cb->filter_opaque = filter_opaque;
    cb->legacy = legacy;

    if (VIR_APPEND_ELEMENT(cbList->callbacks, cbList->count, cb) < 0)
        goto cleanup;

    /* When additional filtering is being done, every client callback
     * is matched to exactly one server callback.  */
    if (filter) {
        ret = 1;
    } else {
        ret = virObjectEventCallbackListCount(conn, cbList, klass, eventID,
                                              key, serverFilter);
        if (serverFilter && remoteID < 0)
            ret++;
    }

 cleanup:
    virObjectEventCallbackFree(cb);
    return ret;
}