Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
wolfSSL
Date:
Tue May 02 08:44:26 2017 +0000
Revision:
6:fa3bd0ca5896
wolfSSL3.10.2;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 6:fa3bd0ca5896 1 /* wolfevent.c
wolfSSL 6:fa3bd0ca5896 2 *
wolfSSL 6:fa3bd0ca5896 3 * Copyright (C) 2006-2016 wolfSSL Inc.
wolfSSL 6:fa3bd0ca5896 4 *
wolfSSL 6:fa3bd0ca5896 5 * This file is part of wolfSSL.
wolfSSL 6:fa3bd0ca5896 6 *
wolfSSL 6:fa3bd0ca5896 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 6:fa3bd0ca5896 8 * it under the terms of the GNU General Public License as published by
wolfSSL 6:fa3bd0ca5896 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 6:fa3bd0ca5896 10 * (at your option) any later version.
wolfSSL 6:fa3bd0ca5896 11 *
wolfSSL 6:fa3bd0ca5896 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 6:fa3bd0ca5896 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 6:fa3bd0ca5896 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 6:fa3bd0ca5896 15 * GNU General Public License for more details.
wolfSSL 6:fa3bd0ca5896 16 *
wolfSSL 6:fa3bd0ca5896 17 * You should have received a copy of the GNU General Public License
wolfSSL 6:fa3bd0ca5896 18 * along with this program; if not, write to the Free Software
wolfSSL 6:fa3bd0ca5896 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 6:fa3bd0ca5896 20 */
wolfSSL 6:fa3bd0ca5896 21
wolfSSL 6:fa3bd0ca5896 22 #ifdef HAVE_CONFIG_H
wolfSSL 6:fa3bd0ca5896 23 #include <config.h>
wolfSSL 6:fa3bd0ca5896 24 #endif
wolfSSL 6:fa3bd0ca5896 25
wolfSSL 6:fa3bd0ca5896 26 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 6:fa3bd0ca5896 27
wolfSSL 6:fa3bd0ca5896 28
wolfSSL 6:fa3bd0ca5896 29 #ifdef HAVE_WOLF_EVENT
wolfSSL 6:fa3bd0ca5896 30
wolfSSL 6:fa3bd0ca5896 31 #include <wolfssl/internal.h>
wolfSSL 6:fa3bd0ca5896 32 #include <wolfssl/error-ssl.h>
wolfSSL 6:fa3bd0ca5896 33 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 6:fa3bd0ca5896 34
wolfSSL 6:fa3bd0ca5896 35 #include <wolfssl/wolfcrypt/wolfevent.h>
wolfSSL 6:fa3bd0ca5896 36
wolfSSL 6:fa3bd0ca5896 37
wolfSSL 6:fa3bd0ca5896 38 int wolfEvent_Init(WOLF_EVENT* event, WOLF_EVENT_TYPE type, void* context)
wolfSSL 6:fa3bd0ca5896 39 {
wolfSSL 6:fa3bd0ca5896 40 if (event == NULL) {
wolfSSL 6:fa3bd0ca5896 41 return BAD_FUNC_ARG;
wolfSSL 6:fa3bd0ca5896 42 }
wolfSSL 6:fa3bd0ca5896 43
wolfSSL 6:fa3bd0ca5896 44 if (event->pending) {
wolfSSL 6:fa3bd0ca5896 45 WOLFSSL_MSG("event already pending!");
wolfSSL 6:fa3bd0ca5896 46 return BAD_COND_E;
wolfSSL 6:fa3bd0ca5896 47 }
wolfSSL 6:fa3bd0ca5896 48
wolfSSL 6:fa3bd0ca5896 49 XMEMSET(event, 0, sizeof(WOLF_EVENT));
wolfSSL 6:fa3bd0ca5896 50 event->type = type;
wolfSSL 6:fa3bd0ca5896 51 event->context = context;
wolfSSL 6:fa3bd0ca5896 52
wolfSSL 6:fa3bd0ca5896 53 return 0;
wolfSSL 6:fa3bd0ca5896 54 }
wolfSSL 6:fa3bd0ca5896 55
wolfSSL 6:fa3bd0ca5896 56 int wolfEvent_Poll(WOLF_EVENT* event, WOLF_EVENT_FLAG flags)
wolfSSL 6:fa3bd0ca5896 57 {
wolfSSL 6:fa3bd0ca5896 58 int ret = BAD_COND_E;
wolfSSL 6:fa3bd0ca5896 59
wolfSSL 6:fa3bd0ca5896 60 /* Check hardware */
wolfSSL 6:fa3bd0ca5896 61 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 6:fa3bd0ca5896 62 if (event->type >= WOLF_EVENT_TYPE_ASYNC_FIRST &&
wolfSSL 6:fa3bd0ca5896 63 event->type <= WOLF_EVENT_TYPE_ASYNC_LAST)
wolfSSL 6:fa3bd0ca5896 64 {
wolfSSL 6:fa3bd0ca5896 65 ret = wolfAsync_EventPoll(event, flags);
wolfSSL 6:fa3bd0ca5896 66 }
wolfSSL 6:fa3bd0ca5896 67 #endif /* WOLFSSL_ASYNC_CRYPT */
wolfSSL 6:fa3bd0ca5896 68
wolfSSL 6:fa3bd0ca5896 69 return ret;
wolfSSL 6:fa3bd0ca5896 70 }
wolfSSL 6:fa3bd0ca5896 71
wolfSSL 6:fa3bd0ca5896 72 int wolfEventQueue_Init(WOLF_EVENT_QUEUE* queue)
wolfSSL 6:fa3bd0ca5896 73 {
wolfSSL 6:fa3bd0ca5896 74 int ret = 0;
wolfSSL 6:fa3bd0ca5896 75
wolfSSL 6:fa3bd0ca5896 76 if (queue == NULL) {
wolfSSL 6:fa3bd0ca5896 77 return BAD_FUNC_ARG;
wolfSSL 6:fa3bd0ca5896 78 }
wolfSSL 6:fa3bd0ca5896 79
wolfSSL 6:fa3bd0ca5896 80 XMEMSET(queue, 0, sizeof(WOLF_EVENT_QUEUE));
wolfSSL 6:fa3bd0ca5896 81 #ifndef SINGLE_THREADED
wolfSSL 6:fa3bd0ca5896 82 ret = wc_InitMutex(&queue->lock);
wolfSSL 6:fa3bd0ca5896 83 #endif
wolfSSL 6:fa3bd0ca5896 84 return ret;
wolfSSL 6:fa3bd0ca5896 85 }
wolfSSL 6:fa3bd0ca5896 86
wolfSSL 6:fa3bd0ca5896 87
wolfSSL 6:fa3bd0ca5896 88 int wolfEventQueue_Push(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event)
wolfSSL 6:fa3bd0ca5896 89 {
wolfSSL 6:fa3bd0ca5896 90 int ret;
wolfSSL 6:fa3bd0ca5896 91
wolfSSL 6:fa3bd0ca5896 92 if (queue == NULL || event == NULL) {
wolfSSL 6:fa3bd0ca5896 93 return BAD_FUNC_ARG;
wolfSSL 6:fa3bd0ca5896 94 }
wolfSSL 6:fa3bd0ca5896 95
wolfSSL 6:fa3bd0ca5896 96 #ifndef SINGLE_THREADED
wolfSSL 6:fa3bd0ca5896 97 if ((ret = wc_LockMutex(&queue->lock)) != 0) {
wolfSSL 6:fa3bd0ca5896 98 return ret;
wolfSSL 6:fa3bd0ca5896 99 }
wolfSSL 6:fa3bd0ca5896 100 #endif
wolfSSL 6:fa3bd0ca5896 101
wolfSSL 6:fa3bd0ca5896 102 /* Setup event */
wolfSSL 6:fa3bd0ca5896 103 event->next = NULL;
wolfSSL 6:fa3bd0ca5896 104 event->pending = 1;
wolfSSL 6:fa3bd0ca5896 105
wolfSSL 6:fa3bd0ca5896 106 if (queue->tail == NULL) {
wolfSSL 6:fa3bd0ca5896 107 queue->head = event;
wolfSSL 6:fa3bd0ca5896 108 }
wolfSSL 6:fa3bd0ca5896 109 else {
wolfSSL 6:fa3bd0ca5896 110 queue->tail->next = event;
wolfSSL 6:fa3bd0ca5896 111 event->prev = queue->tail;
wolfSSL 6:fa3bd0ca5896 112 }
wolfSSL 6:fa3bd0ca5896 113 queue->tail = event; /* add to the end either way */
wolfSSL 6:fa3bd0ca5896 114 queue->count++;
wolfSSL 6:fa3bd0ca5896 115 ret = 0;
wolfSSL 6:fa3bd0ca5896 116
wolfSSL 6:fa3bd0ca5896 117 #ifndef SINGLE_THREADED
wolfSSL 6:fa3bd0ca5896 118 wc_UnLockMutex(&queue->lock);
wolfSSL 6:fa3bd0ca5896 119 #endif
wolfSSL 6:fa3bd0ca5896 120
wolfSSL 6:fa3bd0ca5896 121 return ret;
wolfSSL 6:fa3bd0ca5896 122 }
wolfSSL 6:fa3bd0ca5896 123
wolfSSL 6:fa3bd0ca5896 124 int wolfEventQueue_Pop(WOLF_EVENT_QUEUE* queue, WOLF_EVENT** event)
wolfSSL 6:fa3bd0ca5896 125 {
wolfSSL 6:fa3bd0ca5896 126 int ret = 0;
wolfSSL 6:fa3bd0ca5896 127
wolfSSL 6:fa3bd0ca5896 128 if (queue == NULL || event == NULL) {
wolfSSL 6:fa3bd0ca5896 129 return BAD_FUNC_ARG;
wolfSSL 6:fa3bd0ca5896 130 }
wolfSSL 6:fa3bd0ca5896 131
wolfSSL 6:fa3bd0ca5896 132 #ifndef SINGLE_THREADED
wolfSSL 6:fa3bd0ca5896 133 /* In single threaded mode "event_queue.lock" doesn't exist */
wolfSSL 6:fa3bd0ca5896 134 if ((ret = wc_LockMutex(&queue->lock)) != 0) {
wolfSSL 6:fa3bd0ca5896 135 return ret;
wolfSSL 6:fa3bd0ca5896 136 }
wolfSSL 6:fa3bd0ca5896 137 #endif
wolfSSL 6:fa3bd0ca5896 138
wolfSSL 6:fa3bd0ca5896 139 /* Pop first item off queue */
wolfSSL 6:fa3bd0ca5896 140 *event = queue->head;
wolfSSL 6:fa3bd0ca5896 141 ret = wolfEventQueue_Remove(queue, *event);
wolfSSL 6:fa3bd0ca5896 142
wolfSSL 6:fa3bd0ca5896 143 #ifndef SINGLE_THREADED
wolfSSL 6:fa3bd0ca5896 144 wc_UnLockMutex(&queue->lock);
wolfSSL 6:fa3bd0ca5896 145 #endif
wolfSSL 6:fa3bd0ca5896 146
wolfSSL 6:fa3bd0ca5896 147 return ret;
wolfSSL 6:fa3bd0ca5896 148 }
wolfSSL 6:fa3bd0ca5896 149
wolfSSL 6:fa3bd0ca5896 150 /* assumes queue is locked by caller */
wolfSSL 6:fa3bd0ca5896 151 int wolfEventQueue_Remove(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event)
wolfSSL 6:fa3bd0ca5896 152 {
wolfSSL 6:fa3bd0ca5896 153 int ret = 0;
wolfSSL 6:fa3bd0ca5896 154
wolfSSL 6:fa3bd0ca5896 155 if (queue == NULL || event == NULL) {
wolfSSL 6:fa3bd0ca5896 156 return BAD_FUNC_ARG;
wolfSSL 6:fa3bd0ca5896 157 }
wolfSSL 6:fa3bd0ca5896 158
wolfSSL 6:fa3bd0ca5896 159 if (event == queue->head && event == queue->tail) {
wolfSSL 6:fa3bd0ca5896 160 queue->head = NULL;
wolfSSL 6:fa3bd0ca5896 161 queue->tail = NULL;
wolfSSL 6:fa3bd0ca5896 162 }
wolfSSL 6:fa3bd0ca5896 163 else if (event == queue->head) {
wolfSSL 6:fa3bd0ca5896 164 queue->head = event->next;
wolfSSL 6:fa3bd0ca5896 165 queue->head->prev = NULL;
wolfSSL 6:fa3bd0ca5896 166 }
wolfSSL 6:fa3bd0ca5896 167 else if (event == queue->tail) {
wolfSSL 6:fa3bd0ca5896 168 queue->tail = event->prev;
wolfSSL 6:fa3bd0ca5896 169 queue->tail->next = NULL;
wolfSSL 6:fa3bd0ca5896 170 }
wolfSSL 6:fa3bd0ca5896 171 else {
wolfSSL 6:fa3bd0ca5896 172 WOLF_EVENT* next = event->next;
wolfSSL 6:fa3bd0ca5896 173 WOLF_EVENT* prev = event->prev;
wolfSSL 6:fa3bd0ca5896 174 next->prev = prev;
wolfSSL 6:fa3bd0ca5896 175 prev->next = next;
wolfSSL 6:fa3bd0ca5896 176 }
wolfSSL 6:fa3bd0ca5896 177 queue->count--;
wolfSSL 6:fa3bd0ca5896 178
wolfSSL 6:fa3bd0ca5896 179 return ret;
wolfSSL 6:fa3bd0ca5896 180 }
wolfSSL 6:fa3bd0ca5896 181
wolfSSL 6:fa3bd0ca5896 182 int wolfEventQueue_Poll(WOLF_EVENT_QUEUE* queue, void* context_filter,
wolfSSL 6:fa3bd0ca5896 183 WOLF_EVENT** events, int maxEvents, WOLF_EVENT_FLAG flags, int* eventCount)
wolfSSL 6:fa3bd0ca5896 184 {
wolfSSL 6:fa3bd0ca5896 185 WOLF_EVENT* event;
wolfSSL 6:fa3bd0ca5896 186 int ret = 0, count = 0;
wolfSSL 6:fa3bd0ca5896 187
wolfSSL 6:fa3bd0ca5896 188 if (queue == NULL) {
wolfSSL 6:fa3bd0ca5896 189 return BAD_FUNC_ARG;
wolfSSL 6:fa3bd0ca5896 190 }
wolfSSL 6:fa3bd0ca5896 191
wolfSSL 6:fa3bd0ca5896 192 #ifndef SINGLE_THREADED
wolfSSL 6:fa3bd0ca5896 193 /* In single threaded mode "event_queue.lock" doesn't exist */
wolfSSL 6:fa3bd0ca5896 194 if ((ret = wc_LockMutex(&queue->lock)) != 0) {
wolfSSL 6:fa3bd0ca5896 195 return ret;
wolfSSL 6:fa3bd0ca5896 196 }
wolfSSL 6:fa3bd0ca5896 197 #endif
wolfSSL 6:fa3bd0ca5896 198
wolfSSL 6:fa3bd0ca5896 199 /* itterate event queue */
wolfSSL 6:fa3bd0ca5896 200 for (event = queue->head; event != NULL; event = event->next)
wolfSSL 6:fa3bd0ca5896 201 {
wolfSSL 6:fa3bd0ca5896 202 /* optional filter based on context */
wolfSSL 6:fa3bd0ca5896 203 if (context_filter == NULL || event->context == context_filter) {
wolfSSL 6:fa3bd0ca5896 204
wolfSSL 6:fa3bd0ca5896 205 /* poll event */
wolfSSL 6:fa3bd0ca5896 206 ret = wolfEvent_Poll(event, flags);
wolfSSL 6:fa3bd0ca5896 207 if (ret < 0) break; /* exit for */
wolfSSL 6:fa3bd0ca5896 208
wolfSSL 6:fa3bd0ca5896 209 /* If event is done then process */
wolfSSL 6:fa3bd0ca5896 210 if (event->done) {
wolfSSL 6:fa3bd0ca5896 211 /* remove from queue */
wolfSSL 6:fa3bd0ca5896 212 ret = wolfEventQueue_Remove(queue, event);
wolfSSL 6:fa3bd0ca5896 213 if (ret < 0) break; /* exit for */
wolfSSL 6:fa3bd0ca5896 214
wolfSSL 6:fa3bd0ca5896 215 /* return pointer in 'events' arg */
wolfSSL 6:fa3bd0ca5896 216 if (events) {
wolfSSL 6:fa3bd0ca5896 217 events[count] = event; /* return pointer */
wolfSSL 6:fa3bd0ca5896 218 }
wolfSSL 6:fa3bd0ca5896 219 count++;
wolfSSL 6:fa3bd0ca5896 220
wolfSSL 6:fa3bd0ca5896 221 /* check to make sure our event list isn't full */
wolfSSL 6:fa3bd0ca5896 222 if (events && count >= maxEvents) {
wolfSSL 6:fa3bd0ca5896 223 break; /* exit for */
wolfSSL 6:fa3bd0ca5896 224 }
wolfSSL 6:fa3bd0ca5896 225 }
wolfSSL 6:fa3bd0ca5896 226 }
wolfSSL 6:fa3bd0ca5896 227 }
wolfSSL 6:fa3bd0ca5896 228
wolfSSL 6:fa3bd0ca5896 229 #ifndef SINGLE_THREADED
wolfSSL 6:fa3bd0ca5896 230 wc_UnLockMutex(&queue->lock);
wolfSSL 6:fa3bd0ca5896 231 #endif
wolfSSL 6:fa3bd0ca5896 232
wolfSSL 6:fa3bd0ca5896 233 /* return number of properly populated events */
wolfSSL 6:fa3bd0ca5896 234 if (eventCount) {
wolfSSL 6:fa3bd0ca5896 235 *eventCount = count;
wolfSSL 6:fa3bd0ca5896 236 }
wolfSSL 6:fa3bd0ca5896 237
wolfSSL 6:fa3bd0ca5896 238 return ret;
wolfSSL 6:fa3bd0ca5896 239 }
wolfSSL 6:fa3bd0ca5896 240
wolfSSL 6:fa3bd0ca5896 241 int wolfEventQueue_Count(WOLF_EVENT_QUEUE* queue)
wolfSSL 6:fa3bd0ca5896 242 {
wolfSSL 6:fa3bd0ca5896 243 int ret;
wolfSSL 6:fa3bd0ca5896 244
wolfSSL 6:fa3bd0ca5896 245 if (queue == NULL) {
wolfSSL 6:fa3bd0ca5896 246 return BAD_FUNC_ARG;
wolfSSL 6:fa3bd0ca5896 247 }
wolfSSL 6:fa3bd0ca5896 248
wolfSSL 6:fa3bd0ca5896 249 #ifndef SINGLE_THREADED
wolfSSL 6:fa3bd0ca5896 250 /* In single threaded mode "event_queue.lock" doesn't exist */
wolfSSL 6:fa3bd0ca5896 251 if ((ret = wc_LockMutex(&queue->lock)) != 0) {
wolfSSL 6:fa3bd0ca5896 252 return ret;
wolfSSL 6:fa3bd0ca5896 253 }
wolfSSL 6:fa3bd0ca5896 254 #endif
wolfSSL 6:fa3bd0ca5896 255
wolfSSL 6:fa3bd0ca5896 256 ret = queue->count;
wolfSSL 6:fa3bd0ca5896 257
wolfSSL 6:fa3bd0ca5896 258 #ifndef SINGLE_THREADED
wolfSSL 6:fa3bd0ca5896 259 wc_UnLockMutex(&queue->lock);
wolfSSL 6:fa3bd0ca5896 260 #endif
wolfSSL 6:fa3bd0ca5896 261
wolfSSL 6:fa3bd0ca5896 262 return ret;
wolfSSL 6:fa3bd0ca5896 263 }
wolfSSL 6:fa3bd0ca5896 264
wolfSSL 6:fa3bd0ca5896 265 void wolfEventQueue_Free(WOLF_EVENT_QUEUE* queue)
wolfSSL 6:fa3bd0ca5896 266 {
wolfSSL 6:fa3bd0ca5896 267 if (queue) {
wolfSSL 6:fa3bd0ca5896 268 #ifndef SINGLE_THREADED
wolfSSL 6:fa3bd0ca5896 269 wc_FreeMutex(&queue->lock);
wolfSSL 6:fa3bd0ca5896 270 #endif
wolfSSL 6:fa3bd0ca5896 271 }
wolfSSL 6:fa3bd0ca5896 272 }
wolfSSL 6:fa3bd0ca5896 273
wolfSSL 6:fa3bd0ca5896 274 #endif /* HAVE_WOLF_EVENT */
wolfSSL 6:fa3bd0ca5896 275