/* * BRLTTY - A background process providing access to the console screen (when in * text mode) for a blind person using a refreshable braille display. * * Copyright (C) 1995-2021 by The BRLTTY Developers. * * BRLTTY comes with ABSOLUTELY NO WARRANTY. * * This is free software, placed 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. Please see the file LICENSE-LGPL for details. * * Web Page: http://brltty.app/ * * This software is maintained by Dave Mielke . */ #include "prologue.h" #include #include "log.h" #include "async_internal.h" struct AsyncHandleStruct { Element *element; int identifier; AsyncThreadSpecificData *tsd; }; int asyncMakeHandle ( AsyncHandle *handle, Element *(*newElement) (const void *parameters), const void *parameters ) { if (handle) { if (!(*handle = malloc(sizeof(**handle)))) { logMallocError(); return 0; } } { Element *element = newElement(parameters); if (element) { if (handle) { memset(*handle, 0, sizeof(**handle)); (*handle)->element = element; (*handle)->identifier = getElementIdentifier(element); (*handle)->tsd = asyncGetThreadSpecificData(); } return 1; } } if (handle) free(*handle); return 0; } int asyncTestHandle (AsyncHandle handle) { AsyncThreadSpecificData *tsd = asyncGetThreadSpecificData(); if (handle->tsd == tsd) return 1; logMessage(LOG_WARNING, "invalid async handle"); return 0; } Element * asyncGetHandleElement (AsyncHandle handle, const Queue *queue) { if (asyncTestHandle(handle)) { if (queue) { Element *element = handle->element; if (handle->identifier == getElementIdentifier(element)) { if ((queue == ASYNC_ANY_QUEUE) || (queue == getElementQueue(element))) { return element; } } } } return NULL; } void asyncDiscardHandle (AsyncHandle handle) { free(handle); } void asyncCancelRequest (AsyncHandle handle) { Element *element = asyncGetHandleElement(handle, ASYNC_ANY_QUEUE); asyncDiscardHandle(handle); if (element) { Queue *queue = getElementQueue(element); const AsyncQueueMethods *methods = getQueueData(queue); if (methods) { if (methods->cancelRequest) { methods->cancelRequest(element); return; } } deleteElement(element); } } typedef struct { Element *element; } ElementHandleParameters; static Element * newElementHandle (const void *parameters) { const ElementHandleParameters *ehp = parameters; return ehp->element; } int asyncMakeElementHandle (AsyncHandle *handle, Element *element) { const ElementHandleParameters ehp = { .element = element }; return asyncMakeHandle(handle, newElementHandle, &ehp); }