2 #include "wilc_oswrapper.h"
3 #include <linux/spinlock.h>
8 * @note copied from FLO glue implementatuion
11 WILC_ErrNo WILC_MsgQueueCreate(WILC_MsgQueueHandle *pHandle,
12 tstrWILC_MsgQueueAttrs *pstrAttrs)
14 tstrWILC_SemaphoreAttrs strSemAttrs;
15 WILC_SemaphoreFillDefault(&strSemAttrs);
16 strSemAttrs.u32InitCount = 0;
18 spin_lock_init(&pHandle->strCriticalSection);
19 if ((WILC_SemaphoreCreate(&pHandle->hSem, &strSemAttrs) == WILC_SUCCESS)) {
21 pHandle->pstrMessageList = NULL;
22 pHandle->u32ReceiversCount = 0;
23 pHandle->bExiting = WILC_FALSE;
34 * @note copied from FLO glue implementatuion
37 WILC_ErrNo WILC_MsgQueueDestroy(WILC_MsgQueueHandle *pHandle,
38 tstrWILC_MsgQueueAttrs *pstrAttrs)
41 pHandle->bExiting = WILC_TRUE;
43 /* Release any waiting receiver thread. */
44 while (pHandle->u32ReceiversCount > 0) {
45 WILC_SemaphoreRelease(&(pHandle->hSem), WILC_NULL);
46 pHandle->u32ReceiversCount--;
49 WILC_SemaphoreDestroy(&pHandle->hSem, WILC_NULL);
51 while (pHandle->pstrMessageList != NULL) {
52 Message *pstrMessge = pHandle->pstrMessageList->pstrNext;
53 WILC_FREE(pHandle->pstrMessageList);
54 pHandle->pstrMessageList = pstrMessge;
63 * @note copied from FLO glue implementatuion
66 WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle,
67 const void *pvSendBuffer, WILC_Uint32 u32SendBufferSize,
68 tstrWILC_MsgQueueAttrs *pstrAttrs)
70 WILC_ErrNo s32RetStatus = WILC_SUCCESS;
72 Message *pstrMessage = NULL;
74 if ((pHandle == NULL) || (u32SendBufferSize == 0) || (pvSendBuffer == NULL)) {
75 WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT);
78 if (pHandle->bExiting == WILC_TRUE) {
79 WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
82 spin_lock_irqsave(&pHandle->strCriticalSection, flags);
84 /* construct a new message */
85 pstrMessage = WILC_NEW(Message, 1);
86 WILC_NULLCHECK(s32RetStatus, pstrMessage);
87 pstrMessage->u32Length = u32SendBufferSize;
88 pstrMessage->pstrNext = NULL;
89 pstrMessage->pvBuffer = WILC_MALLOC(u32SendBufferSize);
90 WILC_NULLCHECK(s32RetStatus, pstrMessage->pvBuffer);
91 WILC_memcpy(pstrMessage->pvBuffer, pvSendBuffer, u32SendBufferSize);
94 /* add it to the message queue */
95 if (pHandle->pstrMessageList == NULL) {
96 pHandle->pstrMessageList = pstrMessage;
98 Message *pstrTailMsg = pHandle->pstrMessageList;
99 while (pstrTailMsg->pstrNext != NULL) {
100 pstrTailMsg = pstrTailMsg->pstrNext;
102 pstrTailMsg->pstrNext = pstrMessage;
105 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
107 WILC_SemaphoreRelease(&pHandle->hSem, WILC_NULL);
109 WILC_CATCH(s32RetStatus)
111 /* error occured, free any allocations */
112 if (pstrMessage != NULL) {
113 if (pstrMessage->pvBuffer != NULL) {
114 WILC_FREE(pstrMessage->pvBuffer);
116 WILC_FREE(pstrMessage);
128 * @note copied from FLO glue implementatuion
131 WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle,
132 void *pvRecvBuffer, WILC_Uint32 u32RecvBufferSize,
133 WILC_Uint32 *pu32ReceivedLength,
134 tstrWILC_MsgQueueAttrs *pstrAttrs)
137 Message *pstrMessage;
138 WILC_ErrNo s32RetStatus = WILC_SUCCESS;
139 tstrWILC_SemaphoreAttrs strSemAttrs;
141 if ((pHandle == NULL) || (u32RecvBufferSize == 0)
142 || (pvRecvBuffer == NULL) || (pu32ReceivedLength == NULL)) {
143 WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT);
146 if (pHandle->bExiting == WILC_TRUE) {
147 WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
150 spin_lock_irqsave(&pHandle->strCriticalSection, flags);
151 pHandle->u32ReceiversCount++;
152 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
154 WILC_SemaphoreFillDefault(&strSemAttrs);
155 s32RetStatus = WILC_SemaphoreAcquire(&(pHandle->hSem), &strSemAttrs);
156 if (s32RetStatus == WILC_TIMEOUT) {
157 /* timed out, just exit without consumeing the message */
158 spin_lock_irqsave(&pHandle->strCriticalSection, flags);
159 pHandle->u32ReceiversCount--;
160 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
162 /* other non-timeout scenarios */
163 WILC_ERRORCHECK(s32RetStatus);
165 if (pHandle->bExiting) {
166 WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
169 spin_lock_irqsave(&pHandle->strCriticalSection, flags);
171 pstrMessage = pHandle->pstrMessageList;
172 if (pstrMessage == NULL) {
173 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
174 WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
176 /* check buffer size */
177 if (u32RecvBufferSize < pstrMessage->u32Length) {
178 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
179 WILC_SemaphoreRelease(&pHandle->hSem, WILC_NULL);
180 WILC_ERRORREPORT(s32RetStatus, WILC_BUFFER_OVERFLOW);
183 /* consume the message */
184 pHandle->u32ReceiversCount--;
185 WILC_memcpy(pvRecvBuffer, pstrMessage->pvBuffer, pstrMessage->u32Length);
186 *pu32ReceivedLength = pstrMessage->u32Length;
188 pHandle->pstrMessageList = pstrMessage->pstrNext;
190 WILC_FREE(pstrMessage->pvBuffer);
191 WILC_FREE(pstrMessage);
193 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
197 WILC_CATCH(s32RetStatus)