int asyncExecuteAlarmCallback (AsyncAlarmData *ad, long int *timeout) { if (ad) { Queue *alarms = ad->alarmQueue; if (alarms) { Element *element = processQueue(alarms, testInactiveAlarm, NULL); if (element) { AlarmEntry *alarm = getElementItem(element); TimeValue now; long int milliseconds; getMonotonicTime(&now); milliseconds = millisecondsBetween(&now, &alarm->time); if (milliseconds <= 0) { AsyncAlarmCallback *callback = alarm->callback; const AsyncAlarmCallbackParameters parameters = { .now = &now, .data = alarm->data }; logSymbol(LOG_CATEGORY(ASYNC_EVENTS), callback, "alarm starting"); alarm->active = 1; if (callback) callback(¶meters); alarm->active = 0; if (alarm->reschedule) { adjustTimeValue(&alarm->time, alarm->interval); getMonotonicTime(&now); if (compareTimeValues(&alarm->time, &now) < 0) alarm->time = now; requeueElement(element); } else { alarm->cancel = 1; } if (alarm->cancel) deleteElement(element); return 1; } if (milliseconds < *timeout) { *timeout = milliseconds; logSymbol(LOG_CATEGORY(ASYNC_EVENTS), alarm->callback, "next alarm: %ld", *timeout); } } } } return 0; }
int asyncResetAlarmTo (AsyncHandle handle, const TimeValue *time) { Element *element = getAlarmElement(handle); if (element) { AlarmEntry *alarm = getElementItem(element); alarm->time = *time; requeueElement(element); return 1; } return 0; }
int asyncExecuteIoCallback (AsyncIoData *iod, long int timeout) { if (iod) { Queue *functions = iod->functionQueue; unsigned int functionCount = functions? getQueueSize(functions): 0; prepareMonitors(); if (functionCount) { MonitorEntry monitorArray[functionCount]; MonitorGroup monitors = { .array = monitorArray, .count = 0 }; int executed = 0; Element *functionElement = processQueue(functions, addFunctionMonitor, &monitors); if (!functionElement) { if (!monitors.count) { approximateDelay(timeout); } else if (awaitMonitors(&monitors, timeout)) { functionElement = processQueue(functions, testFunctionMonitor, NULL); } } if (functionElement) { FunctionEntry *function = getElementItem(functionElement); Element *operationElement = getActiveOperationElement(function); OperationEntry *operation = getElementItem(operationElement); if (!operation->finished) finishOperation(operation); operation->active = 1; if (!function->methods->invokeCallback(operation)) operation->cancel = 1; operation->active = 0; executed = 1; if (operation->cancel) { deleteElement(operationElement); } else { operation->error = 0; } if ((operationElement = getActiveOperationElement(function))) { operation = getElementItem(operationElement); if (!operation->finished) startOperation(operation); requeueElement(functionElement); } else { deleteElement(functionElement); } } return executed; } } approximateDelay(timeout); return 0; } static void deallocateOperationEntry (void *item, void *data) { OperationEntry *operation = item; if (operation->extension) free(operation->extension); free(operation); }