static void virObjectEventStateFlush(virObjectEventStatePtr state) { virObjectEventQueue tempQueue; /* We need to lock as well as ref due to the fact that we might * unref the state we're working on in this very function */ virObjectRef(state); virObjectLock(state); state->isDispatching = true; /* Copy the queue, so we're reentrant safe when dispatchFunc drops the * driver lock */ tempQueue.count = state->queue->count; tempQueue.events = state->queue->events; state->queue->count = 0; state->queue->events = NULL; if (state->timer != -1) virEventUpdateTimeout(state->timer, -1); virObjectEventStateQueueDispatch(state, &tempQueue, state->callbacks); /* Purge any deleted callbacks */ virObjectEventCallbackListPurgeMarked(state->callbacks); /* If we purged all callbacks, we need to remove the timeout as * well like virObjectEventStateDeregisterID() would do. */ virObjectEventStateCleanupTimer(state, true); state->isDispatching = false; virObjectUnlock(state); virObjectUnref(state); }
static void virObjectEventStateFlush(virObjectEventStatePtr state) { virObjectEventQueue tempQueue; virObjectEventStateLock(state); state->isDispatching = true; /* Copy the queue, so we're reentrant safe when dispatchFunc drops the * driver lock */ tempQueue.count = state->queue->count; tempQueue.events = state->queue->events; state->queue->count = 0; state->queue->events = NULL; virEventUpdateTimeout(state->timer, -1); virObjectEventStateQueueDispatch(state, &tempQueue, state->callbacks); /* Purge any deleted callbacks */ virObjectEventCallbackListPurgeMarked(state->callbacks); state->isDispatching = false; virObjectEventStateUnlock(state); }
/** * virObjectEventStateQueueRemote: * @state: the event state object * @event: event to add to the queue * @remoteID: limit dispatch to callbacks with the same remote id * * Adds @event to the queue of events to be dispatched at the next * safe moment. The caller should no longer use @event after this * call. If @remoteID is non-negative, the event will only be sent to * callbacks where virObjectEventStateSetRemote() registered a remote * id. */ void virObjectEventStateQueueRemote(virObjectEventStatePtr state, virObjectEventPtr event, int remoteID) { if (!event) return; if (state->timer < 0) { virObjectUnref(event); return; } virObjectLock(state); event->remoteID = remoteID; if (virObjectEventQueuePush(state->queue, event) < 0) { VIR_DEBUG("Error adding event to queue"); virObjectUnref(event); } if (state->queue->count == 1) virEventUpdateTimeout(state->timer, 0); virObjectUnlock(state); }
static void virNetClientStreamEventTimerUpdate(virNetClientStreamPtr st) { if (!st->cb) return; VIR_DEBUG("Check timer offset=%zu %d", st->incomingOffset, st->cbEvents); if (((st->incomingOffset || st->incomingEOF) && (st->cbEvents & VIR_STREAM_EVENT_READABLE)) || (st->cbEvents & VIR_STREAM_EVENT_WRITABLE)) { VIR_DEBUG("Enabling event timer"); virEventUpdateTimeout(st->cbTimer, 0); } else { VIR_DEBUG("Disabling event timer"); virEventUpdateTimeout(st->cbTimer, -1); } }
static void virNetServerClientSockTimerFunc(int timer, void *opaque) { virNetServerClientPtr client = opaque; virNetServerClientLock(client); virEventUpdateTimeout(timer, -1); /* Although client->rx != NULL when this timer is enabled, it might have * changed since the client was unlocked in the meantime. */ if (client->rx) virNetServerClientDispatchRead(client); virNetServerClientUnlock(client); }
static void virLXCControllerClientCloseHook(virNetServerClientPtr client) { virLXCControllerPtr ctrl = virNetServerClientGetPrivateData(client); VIR_DEBUG("Client %p has closed", client); if (ctrl->client == client) ctrl->client = NULL; if (ctrl->inShutdown) { VIR_DEBUG("Arm timer to quit event loop"); virEventUpdateTimeout(ctrl->timerShutdown, 0); } }
/* * @client: a locked client object */ static void virNetServerClientUpdateEvent(virNetServerClientPtr client) { int mode; if (!client->sock) return; mode = virNetServerClientCalculateHandleMode(client); virNetSocketUpdateIOCallback(client->sock, mode); if (client->rx && virNetSocketHasCachedData(client->sock)) virEventUpdateTimeout(client->sockTimer, 0); }
bool virKeepAliveCheckMessage(virKeepAlivePtr ka, virNetMessagePtr msg, virNetMessagePtr *response) { bool ret = false; VIR_DEBUG("ka=%p, client=%p, msg=%p", ka, ka ? ka->client : "(null)", msg); *response = NULL; if (!ka) return false; virObjectLock(ka); ka->countToDeath = ka->count; ka->lastPacketReceived = ka->intervalStart = time(NULL); if (msg->header.prog == KEEPALIVE_PROGRAM && msg->header.vers == KEEPALIVE_PROTOCOL_VERSION && msg->header.type == VIR_NET_MESSAGE) { PROBE(RPC_KEEPALIVE_RECEIVED, "ka=%p client=%p prog=%d vers=%d proc=%d", ka, ka->client, msg->header.prog, msg->header.vers, msg->header.proc); ret = true; switch (msg->header.proc) { case KEEPALIVE_PROC_PING: VIR_DEBUG("Got keepalive request from client %p", ka->client); *response = virKeepAliveMessage(ka, KEEPALIVE_PROC_PONG); break; case KEEPALIVE_PROC_PONG: VIR_DEBUG("Got keepalive response from client %p", ka->client); break; default: VIR_DEBUG("Ignoring unknown keepalive message %d from client %p", msg->header.proc, ka->client); } } if (ka->timer >= 0) virEventUpdateTimeout(ka->timer, ka->interval * 1000); virObjectUnlock(ka); return ret; }
static bool virKeepAliveTimerInternal(virKeepAlivePtr ka, virNetMessagePtr *msg) { time_t now = time(NULL); int timeval; if (ka->interval <= 0 || ka->intervalStart == 0) return false; if (now - ka->intervalStart < ka->interval) { timeval = ka->interval - (now - ka->intervalStart); virEventUpdateTimeout(ka->timer, timeval * 1000); return false; } timeval = now - ka->lastPacketReceived; PROBE(RPC_KEEPALIVE_TIMEOUT, "ka=%p client=%p countToDeath=%d idle=%d", ka, ka->client, ka->countToDeath, timeval); if (ka->countToDeath == 0) { VIR_WARN("No response from client %p after %d keepalive messages in" " %d seconds", ka->client, ka->count, timeval); return true; } else { ka->countToDeath--; ka->intervalStart = now; *msg = virKeepAliveMessage(ka, KEEPALIVE_PROC_PING); virEventUpdateTimeout(ka->timer, ka->interval * 1000); return false; } }