wolfSSL 3.11.1 for TLS1.3 beta
Fork of wolfSSL by
wolfcrypt/src/wolfevent.c
- Committer:
- wolfSSL
- Date:
- 2017-05-30
- Revision:
- 13:80fb167dafdf
- Parent:
- 11:cee25a834751
File content as of revision 13:80fb167dafdf:
/* wolfevent.c * * Copyright (C) 2006-2016 wolfSSL Inc. * * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * wolfSSL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <wolfssl/wolfcrypt/settings.h> #ifdef HAVE_WOLF_EVENT #include <wolfssl/internal.h> #include <wolfssl/error-ssl.h> #include <wolfssl/wolfcrypt/error-crypt.h> #include <wolfssl/wolfcrypt/wolfevent.h> int wolfEvent_Init(WOLF_EVENT* event, WOLF_EVENT_TYPE type, void* context) { if (event == NULL) { return BAD_FUNC_ARG; } if (event->pending) { WOLFSSL_MSG("event already pending!"); return BAD_COND_E; } XMEMSET(event, 0, sizeof(WOLF_EVENT)); event->type = type; event->context = context; return 0; } int wolfEvent_Poll(WOLF_EVENT* event, WOLF_EVENT_FLAG flags) { int ret = BAD_COND_E; /* Check hardware */ #ifdef WOLFSSL_ASYNC_CRYPT if (event->type >= WOLF_EVENT_TYPE_ASYNC_FIRST && event->type <= WOLF_EVENT_TYPE_ASYNC_LAST) { ret = wolfAsync_EventPoll(event, flags); } #endif /* WOLFSSL_ASYNC_CRYPT */ return ret; } int wolfEventQueue_Init(WOLF_EVENT_QUEUE* queue) { int ret = 0; if (queue == NULL) { return BAD_FUNC_ARG; } XMEMSET(queue, 0, sizeof(WOLF_EVENT_QUEUE)); #ifndef SINGLE_THREADED ret = wc_InitMutex(&queue->lock); #endif return ret; } int wolfEventQueue_Push(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event) { int ret; if (queue == NULL || event == NULL) { return BAD_FUNC_ARG; } #ifndef SINGLE_THREADED if ((ret = wc_LockMutex(&queue->lock)) != 0) { return ret; } #endif /* Setup event */ event->next = NULL; event->pending = 1; ret = wolfEventQueue_Add(queue, event); #ifndef SINGLE_THREADED wc_UnLockMutex(&queue->lock); #endif return ret; } int wolfEventQueue_Pop(WOLF_EVENT_QUEUE* queue, WOLF_EVENT** event) { int ret = 0; if (queue == NULL || event == NULL) { return BAD_FUNC_ARG; } #ifndef SINGLE_THREADED /* In single threaded mode "event_queue.lock" doesn't exist */ if ((ret = wc_LockMutex(&queue->lock)) != 0) { return ret; } #endif /* Pop first item off queue */ *event = queue->head; ret = wolfEventQueue_Remove(queue, *event); #ifndef SINGLE_THREADED wc_UnLockMutex(&queue->lock); #endif return ret; } /* assumes queue is locked by caller */ int wolfEventQueue_Add(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event) { if (queue == NULL || event == NULL) { return BAD_FUNC_ARG; } if (queue->tail == NULL) { queue->head = event; } else { queue->tail->next = event; event->prev = queue->tail; } queue->tail = event; /* add to the end either way */ queue->count++; return 0; } /* assumes queue is locked by caller */ int wolfEventQueue_Remove(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event) { int ret = 0; if (queue == NULL || event == NULL) { return BAD_FUNC_ARG; } if (event == queue->head && event == queue->tail) { queue->head = NULL; queue->tail = NULL; } else if (event == queue->head) { queue->head = event->next; queue->head->prev = NULL; } else if (event == queue->tail) { queue->tail = event->prev; queue->tail->next = NULL; } else { WOLF_EVENT* next = event->next; WOLF_EVENT* prev = event->prev; next->prev = prev; prev->next = next; } queue->count--; return ret; } int wolfEventQueue_Poll(WOLF_EVENT_QUEUE* queue, void* context_filter, WOLF_EVENT** events, int maxEvents, WOLF_EVENT_FLAG flags, int* eventCount) { WOLF_EVENT* event; int ret = 0, count = 0; if (queue == NULL) { return BAD_FUNC_ARG; } #ifndef SINGLE_THREADED /* In single threaded mode "event_queue.lock" doesn't exist */ if ((ret = wc_LockMutex(&queue->lock)) != 0) { return ret; } #endif /* itterate event queue */ for (event = queue->head; event != NULL; event = event->next) { /* optional filter based on context */ if (context_filter == NULL || event->context == context_filter) { /* poll event */ ret = wolfEvent_Poll(event, flags); if (ret < 0) break; /* exit for */ /* If event is done then process */ if (event->done) { /* remove from queue */ ret = wolfEventQueue_Remove(queue, event); if (ret < 0) break; /* exit for */ /* return pointer in 'events' arg */ if (events) { events[count] = event; /* return pointer */ } count++; /* check to make sure our event list isn't full */ if (events && count >= maxEvents) { break; /* exit for */ } } } } #ifndef SINGLE_THREADED wc_UnLockMutex(&queue->lock); #endif /* return number of properly populated events */ if (eventCount) { *eventCount = count; } return ret; } int wolfEventQueue_Count(WOLF_EVENT_QUEUE* queue) { int ret; if (queue == NULL) { return BAD_FUNC_ARG; } #ifndef SINGLE_THREADED /* In single threaded mode "event_queue.lock" doesn't exist */ if ((ret = wc_LockMutex(&queue->lock)) != 0) { return ret; } #endif ret = queue->count; #ifndef SINGLE_THREADED wc_UnLockMutex(&queue->lock); #endif return ret; } void wolfEventQueue_Free(WOLF_EVENT_QUEUE* queue) { if (queue) { #ifndef SINGLE_THREADED wc_FreeMutex(&queue->lock); #endif } } #endif /* HAVE_WOLF_EVENT */