wolf SSL / wolfSSL-TLS13-Beta

Fork of wolfSSL by wolf SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers wolfevent.c Source File

wolfevent.c

00001 /* wolfevent.c
00002  *
00003  * Copyright (C) 2006-2016 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * wolfSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
00020  */
00021 
00022 #ifdef HAVE_CONFIG_H
00023     #include <config.h>
00024 #endif
00025 
00026 #include <wolfssl/wolfcrypt/settings.h>
00027 
00028 
00029 #ifdef HAVE_WOLF_EVENT
00030 
00031 #include <wolfssl/internal.h>
00032 #include <wolfssl/error-ssl.h>
00033 #include <wolfssl/wolfcrypt/error-crypt.h>
00034 
00035 #include <wolfssl/wolfcrypt/wolfevent.h>
00036 
00037 
00038 int wolfEvent_Init(WOLF_EVENT* event, WOLF_EVENT_TYPE type, void* context)
00039 {
00040     if (event == NULL) {
00041         return BAD_FUNC_ARG;
00042     }
00043 
00044     if (event->pending) {
00045         WOLFSSL_MSG("event already pending!");
00046         return BAD_COND_E;
00047     }
00048 
00049     XMEMSET(event, 0, sizeof(WOLF_EVENT));
00050     event->type = type;
00051     event->context = context;
00052 
00053     return 0;
00054 }
00055 
00056 int wolfEvent_Poll(WOLF_EVENT* event, WOLF_EVENT_FLAG flags)
00057 {
00058     int ret = BAD_COND_E;
00059 
00060     /* Check hardware */
00061 #ifdef WOLFSSL_ASYNC_CRYPT
00062     if (event->type >= WOLF_EVENT_TYPE_ASYNC_FIRST &&
00063         event->type <= WOLF_EVENT_TYPE_ASYNC_LAST)
00064     {
00065         ret = wolfAsync_EventPoll(event, flags);
00066     }
00067 #endif /* WOLFSSL_ASYNC_CRYPT */
00068 
00069     return ret;
00070 }
00071 
00072 int wolfEventQueue_Init(WOLF_EVENT_QUEUE* queue)
00073 {
00074     int ret = 0;
00075 
00076     if (queue == NULL) {
00077         return BAD_FUNC_ARG;
00078     }
00079 
00080     XMEMSET(queue, 0, sizeof(WOLF_EVENT_QUEUE));
00081 #ifndef SINGLE_THREADED
00082     ret = wc_InitMutex(&queue->lock);
00083 #endif
00084     return ret;
00085 }
00086 
00087 
00088 int wolfEventQueue_Push(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event)
00089 {
00090     int ret;
00091 
00092     if (queue == NULL || event == NULL) {
00093         return BAD_FUNC_ARG;
00094     }
00095 
00096 #ifndef SINGLE_THREADED
00097     if ((ret = wc_LockMutex(&queue->lock)) != 0) {
00098         return ret;
00099     }
00100 #endif
00101 
00102     /* Setup event */
00103     event->next = NULL;
00104     event->pending = 1;
00105 
00106     ret = wolfEventQueue_Add(queue, event);
00107 
00108 #ifndef SINGLE_THREADED
00109     wc_UnLockMutex(&queue->lock);
00110 #endif
00111 
00112     return ret;
00113 }
00114 
00115 int wolfEventQueue_Pop(WOLF_EVENT_QUEUE* queue, WOLF_EVENT** event)
00116 {
00117     int ret = 0;
00118 
00119     if (queue == NULL || event == NULL) {
00120         return BAD_FUNC_ARG;
00121     }
00122 
00123 #ifndef SINGLE_THREADED
00124     /* In single threaded mode "event_queue.lock" doesn't exist */
00125     if ((ret = wc_LockMutex(&queue->lock)) != 0) {
00126         return ret;
00127     }
00128 #endif
00129 
00130     /* Pop first item off queue */
00131     *event = queue->head;
00132     ret = wolfEventQueue_Remove(queue, *event);
00133 
00134 #ifndef SINGLE_THREADED
00135     wc_UnLockMutex(&queue->lock);
00136 #endif
00137 
00138     return ret;
00139 }
00140 
00141 /* assumes queue is locked by caller */
00142 int wolfEventQueue_Add(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event)
00143 {
00144     if (queue == NULL || event == NULL) {
00145         return BAD_FUNC_ARG;
00146     }
00147 
00148     if (queue->tail == NULL)  {
00149         queue->head = event;
00150     }
00151     else {
00152         queue->tail->next = event;
00153         event->prev = queue->tail;
00154     }
00155     queue->tail = event;      /* add to the end either way */
00156     queue->count++;
00157 
00158     return 0;
00159 }
00160 
00161 /* assumes queue is locked by caller */
00162 int wolfEventQueue_Remove(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event)
00163 {
00164     int ret = 0;
00165 
00166     if (queue == NULL || event == NULL) {
00167         return BAD_FUNC_ARG;
00168     }
00169 
00170     if (event == queue->head && event == queue->tail) {
00171         queue->head = NULL;
00172         queue->tail = NULL;
00173     }
00174     else if (event == queue->head) {
00175         queue->head = event->next;
00176         queue->head->prev = NULL;
00177     }
00178     else if (event == queue->tail) {
00179         queue->tail = event->prev;
00180         queue->tail->next = NULL;
00181     }
00182     else {
00183         WOLF_EVENT* next = event->next;
00184         WOLF_EVENT* prev = event->prev;
00185         next->prev = prev;
00186         prev->next = next;
00187     }
00188     queue->count--;
00189 
00190     return ret;
00191 }
00192 
00193 int wolfEventQueue_Poll(WOLF_EVENT_QUEUE* queue, void* context_filter,
00194     WOLF_EVENT** events, int maxEvents, WOLF_EVENT_FLAG flags, int* eventCount)
00195 {
00196     WOLF_EVENT* event;
00197     int ret = 0, count = 0;
00198 
00199     if (queue == NULL) {
00200         return BAD_FUNC_ARG;
00201     }
00202 
00203 #ifndef SINGLE_THREADED
00204     /* In single threaded mode "event_queue.lock" doesn't exist */
00205     if ((ret = wc_LockMutex(&queue->lock)) != 0) {
00206         return ret;
00207     }
00208 #endif
00209 
00210     /* itterate event queue */
00211     for (event = queue->head; event != NULL; event = event->next)
00212     {
00213         /* optional filter based on context */
00214         if (context_filter == NULL || event->context == context_filter) {
00215 
00216             /* poll event */
00217             ret = wolfEvent_Poll(event, flags);
00218             if (ret < 0) break; /* exit for */
00219 
00220             /* If event is done then process */
00221             if (event->done) {
00222                 /* remove from queue */
00223                 ret = wolfEventQueue_Remove(queue, event);
00224                 if (ret < 0) break; /* exit for */
00225 
00226                 /* return pointer in 'events' arg */
00227                 if (events) {
00228                     events[count] = event; /* return pointer */
00229                 }
00230                 count++;
00231 
00232                 /* check to make sure our event list isn't full */
00233                 if (events && count >= maxEvents) {
00234                     break; /* exit for */
00235                 }
00236             }
00237         }
00238     }
00239 
00240 #ifndef SINGLE_THREADED
00241     wc_UnLockMutex(&queue->lock);
00242 #endif
00243 
00244     /* return number of properly populated events */
00245     if (eventCount) {
00246         *eventCount = count;
00247     }
00248 
00249     return ret;
00250 }
00251 
00252 int wolfEventQueue_Count(WOLF_EVENT_QUEUE* queue)
00253 {
00254     int ret;
00255 
00256     if (queue == NULL) {
00257         return BAD_FUNC_ARG;
00258     }
00259 
00260 #ifndef SINGLE_THREADED
00261     /* In single threaded mode "event_queue.lock" doesn't exist */
00262     if ((ret = wc_LockMutex(&queue->lock)) != 0) {
00263         return ret;
00264     }
00265 #endif
00266 
00267     ret = queue->count;
00268 
00269 #ifndef SINGLE_THREADED
00270     wc_UnLockMutex(&queue->lock);
00271 #endif
00272 
00273     return ret;
00274 }
00275 
00276 void wolfEventQueue_Free(WOLF_EVENT_QUEUE* queue)
00277 {
00278     if (queue) {
00279     #ifndef SINGLE_THREADED
00280         wc_FreeMutex(&queue->lock);
00281     #endif
00282     }
00283 }
00284 
00285 #endif /* HAVE_WOLF_EVENT */
00286