Exemple #1
0
/**
 * Deallocates the work queue
 */
STATIC void WKQ_Free(WorkQueue * q)
{
    ASSERT(QUEUE_IsEmpty(&q->submit));
    ASSERT(QUEUE_IsEmpty(&q->items));
    ASSERT(q->flags & WKQ_DEAD);

    EVENT_Destroy(&q->stopEvent);
    EVENT_Destroy(&q->event);
    MUTEX_Destroy(&q->mutex);

    MEM_Free(q);
}
Exemple #2
0
/**
 * Returns the last queue entry or NULL if queue is empty
 */
QEntry * QUEUE_Last(Queue * q)
{
    if (!QUEUE_IsEmpty(q)) {
        return q->head.prev;
    }
    return NULL;
}
Exemple #3
0
/**
 * Returns the first queue entry or NULL if queue is empty
 */
QEntry * QUEUE_First(Queue * q)
{
    if (!QUEUE_IsEmpty(q)) {
        return q->head.next;
    }
    return NULL;
}
Exemple #4
0
alt_u32 QUEUE_Pop(QUEUE_STRUCT *pQueue){
    alt_u32 data32;
    if (QUEUE_IsEmpty(pQueue))
        return 0;
    data32 = pQueue->data[pQueue->rear];
    pQueue->rear = (pQueue->rear+1)%pQueue->num;        
    return data32;
}
Exemple #5
0
/**
 * Waits until all work items associated with this work queue are done ane 
 * deallocates the work queue.
 */
void WKQ_Delete(WorkQueue * q)
{
    if (q) {
        WKQ_Stop(q, True);

        if (q->flags & WKQ_KILLME) {
            ASSERT(QUEUE_Size(&q->items) == 1);
        } else {
            ASSERT(QUEUE_IsEmpty(&q->items));
            WKQ_Free(q);
        }
    }
}
Exemple #6
0
/**
 * Creates the read-only iterator which doesn't support remove operation
 */
Iterator * QUEUE_ConstIterator(const Queue * q)
{
    if (QUEUE_IsEmpty(q)) {
        return ITR_Empty();
    } else {
        QueueIterator * qi = MEM_New(QueueIterator);
        if (qi) {
            ITR_Init(&qi->itr, &queueConstIterator);
            qi->entry = NULL;
            qi->next = q->head.next;
            return &qi->itr;
        } else {
            return NULL;
        }
    }
}
Exemple #7
0
/**
 * Creates the iterator
 */
Iterator * QUEUE_Iterator(Queue * q)
{
    if (QUEUE_IsEmpty(q)) {
        return ITR_Empty();
    } else {
        QueueIterator * qi = MEM_New(QueueIterator);
        if (qi) {
            ITR_Init(&qi->itr, &queueIterator);
            qi->entry = NULL;
            qi->next = QUEUE_First(q);
            return &qi->itr;
        } else {
            return NULL;
        }
    }
}
Exemple #8
0
void ICACHE_FLASH_ATTR
MQTT_Task(os_event_t *e)
{
	MQTT_Client* client = (MQTT_Client*)e->par;
	uint8_t dataBuffer[MQTT_BUF_SIZE];
	uint16_t dataLen;
	if(e->par == 0)
		return;
	switch(client->connState){

	case TCP_RECONNECT_REQ:
		break;
	case TCP_RECONNECT:
		MQTT_Connect(client);
		INFO("TCP: Reconnect to: %s:%d\r\n", client->host, client->port);
		client->connState = TCP_CONNECTING;
		break;
	case MQTT_DATA:
		if(QUEUE_IsEmpty(&client->msgQueue) || client->sendTimeout != 0) {
			break;
		}
		if(QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == 0){
			client->mqtt_state.pending_msg_type = mqtt_get_type(dataBuffer);
			client->mqtt_state.pending_msg_id = mqtt_get_id(dataBuffer, dataLen);


			client->sendTimeout = MQTT_SEND_TIMOUT;
			INFO("MQTT: Sending, type: %d, id: %04X\r\n",client->mqtt_state.pending_msg_type, client->mqtt_state.pending_msg_id);
			if(client->security){
				espconn_secure_sent(client->pCon, dataBuffer, dataLen);
			}
			else{
				espconn_sent(client->pCon, dataBuffer, dataLen);
			}

			client->mqtt_state.outbound_message = NULL;
			break;
		}
		break;
	case TCP_CONNECTING_ERROR:
		MQTT_Disconnect(client);
		MQTT_exit(client);
		break;
	}
}
void FUNCTION_ATTRIBUTE
MQTT_Task(MQTT_Client *client)
{
	INFO("MQTT TASK: state: %d\n", client->connState);
	uint8_t dataBuffer[MQTT_BUF_SIZE];

	uint16_t dataLen;
    struct data_buf buffer;
	if(client == NULL)
		return;
	switch(client->connState){
	case TCP_RECONNECT_REQ:
		break;
	case TCP_RECONNECT:
		MQTT_Connect(client);
		INFO("TCP: Reconnect to: %s:%d\r\n", client->host, client->port);
		client->connState = TCP_CONNECTING;
		break;
	case MQTT_DATA:
		INFO("MQTT TASK DATA\n");
		if(QUEUE_IsEmpty(&client->msgQueue) || client->sendTimeout != 0) {
			break;
		}
		if(QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == 0){
			INFO("%s, dataLen:%d\n", __func__, dataLen);
			client->mqtt_state.pending_msg_type = mqtt_get_type(dataBuffer);
			client->mqtt_state.pending_msg_id = mqtt_get_id(dataBuffer, dataLen);
			client->sendTimeout = MQTT_SEND_TIMOUT;
            buffer.length = dataLen;
            buffer.data = dataBuffer;
			INFO("MQTT: Sending, type: %d, id: %04X\r\n",client->mqtt_state.pending_msg_type, client->mqtt_state.pending_msg_id);
			net_tcp_send(client->pCon, buffer, client->sendTimeout);
			client->mqtt_state.outbound_message = NULL;
			break;
		}
		break;
	case TCP_CONNECTING_ERROR:
		MQTT_Disconnect(client);
		MQTT_exit(client);
		break;
	}
}
Exemple #10
0
void WKQ_Shutdown()
{
    if ((--WKQ.initcount) == 0) {
        while (WKQ.waitpool) {
            Waiter * next = WKQ.waitpool->next;
            EVENT_Destroy(&WKQ.waitpool->event);
            MEM_Free(WKQ.waitpool);
            WKQ.waitpool = next;
            WKQ.nwait--;
        }
        ASSERT(WKQ.nwait == 0);
        while (!QUEUE_IsEmpty(&WKQ.itempool)) {
            QEntry * e = QUEUE_RemoveHead(&WKQ.itempool);
            WorkItem * w = QCAST(e,WorkItem,itemsQ);
            MEM_Free(w);
        }
        MUTEX_Destroy(&WKQ.mutex);
        THREAD_Shutdown();
    }
}
Exemple #11
0
bool MTC_GetStatus(MTC_INFO *p, alt_u8 *Event, alt_u8 *TouchNum, int *X1, int *Y1, int *X2, int *Y2)
{
    bool bFind;
    MTC_EVENT *pEvent;
    
    if (!p)
        return FALSE;

    bFind = QUEUE_IsEmpty(p->pQueue)?FALSE:TRUE;
    if (bFind){
        pEvent = (MTC_EVENT *)QUEUE_Pop(p->pQueue);
        *Event = pEvent->Event;
        *TouchNum = pEvent->TouchNum;
        *X1 = pEvent->x1;
        *Y1 = pEvent->y1;
        *X2 = pEvent->x2;
        *Y2 = pEvent->y2;
        free(pEvent);
    }
    
    return bFind;
}
Exemple #12
0
/**
 * Returns work item from the pool, allocates a new one if needed.
 */
STATIC WorkItem *
WKQ_GetWorkItem(WorkQueueModule * mod, WorkQueue * q, 
    WorkProc cb, WorkProc2 cb2, void * p1, void * p2)
{
    WorkItem * w = NULL;

    ASSERT(mod->initcount > 0);
    /* can't use QUEUE_IsEmpty without synchronization */
    if (!mod->itempool.size) {
        MUTEX_Lock(&mod->mutex);
        if (!QUEUE_IsEmpty(&mod->itempool)) {
            w = QCAST(QUEUE_RemoveHead(&mod->itempool),WorkItem,itemsQ);
            w->flags = 0;
        }
        MUTEX_Unlock(&mod->mutex);
    }

    if (!w) {
        w = MEM_New(WorkItem);
        if (w) {
            memset(w, 0, sizeof(*w));
        }
    }

    if (w) {
        if (MUTEX_Lock(&q->mutex)) {
            w->proc = cb;
            w->proc2 = cb2;
            w->param = p1;
            w->param2 = p2;
            QUEUE_InsertTail(&q->items,&w->itemsQ);
            MUTEX_Unlock(&q->mutex);
            return w;
        }
        MEM_Free(w);
    }

    return NULL;
}
Exemple #13
0
void ICACHE_FLASH_ATTR
MQTT_Task(os_event_t *e)
{
    MQTT_Client* client = (MQTT_Client*)e->par;
    uint8_t dataBuffer[MQTT_BUF_SIZE];
    uint16_t dataLen;
    if (e->par == 0)
        return;
    switch (client->connState) {

    case TCP_RECONNECT_REQ:
        break;
    case TCP_RECONNECT:
        mqtt_tcpclient_delete(client);
        MQTT_Connect(client);
        INFO("TCP: Reconnect to: %s:%d\r\n", client->host, client->port);
        client->connState = TCP_CONNECTING;
        break;
    case MQTT_DELETING:
    case TCP_DISCONNECTING:
    case TCP_RECONNECT_DISCONNECTING:
        if (client->security) {
#ifdef MQTT_SSL_ENABLE
            espconn_secure_disconnect(client->pCon);
#else
            INFO("TCP: Do not support SSL\r\n");
#endif
        }
        else {
            espconn_disconnect(client->pCon);
        }
        break;
    case TCP_DISCONNECTED:
        INFO("MQTT: Disconnected\r\n");
        mqtt_tcpclient_delete(client);
        break;
    case MQTT_DELETED:
        INFO("MQTT: Deleted client\r\n");
        mqtt_client_delete(client);
        break;
    case MQTT_KEEPALIVE_SEND:
        mqtt_send_keepalive(client);
        break;
    case MQTT_DATA:
        if (QUEUE_IsEmpty(&client->msgQueue) || client->sendTimeout != 0) {
            break;
        }
        if (QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == 0) {
            client->mqtt_state.pending_msg_type = mqtt_get_type(dataBuffer);
            client->mqtt_state.pending_msg_id = mqtt_get_id(dataBuffer, dataLen);


            client->sendTimeout = MQTT_SEND_TIMOUT;
            INFO("MQTT: Sending, type: %d, id: %04X\r\n", client->mqtt_state.pending_msg_type, client->mqtt_state.pending_msg_id);
            if (client->security) {
#ifdef MQTT_SSL_ENABLE
                espconn_secure_send(client->pCon, dataBuffer, dataLen);
#else
                INFO("TCP: Do not support SSL\r\n");
#endif
            }
            else {
                espconn_send(client->pCon, dataBuffer, dataLen);
            }

            client->mqtt_state.outbound_message = NULL;
            break;
        }
        break;
    }
}
Exemple #14
0
/**
 * The worker thread
 */
STATIC void WKQ_Thread(void * par) 
{
    WorkQueue * q = (WorkQueue *)par;
    TRACE("WKQ: starting\n");
    
    /* start the loop */
    MUTEX_Lock(&q->mutex);
    q->lastActivity = TIME_Now();
    while ((q->flags & WKQ_ACTIVE) || !QUEUE_IsEmpty(&q->submit)) {
        QEntry * e;
        while ((e = QUEUE_RemoveHead(&q->submit)) != NULL) {
            WorkItem * w = QCAST(e,WorkItem,submitQ);
            ASSERT(!(w->flags & (WKI_DONE|WKI_CANCELED)));

            /*
             * NULL callback may be used by dummy work items whose purpose
             * is to wait until all pending work items have been processed
             */
            if (w->proc) {

                /* update flags */
                w->flags |= WKI_CALL;

                /* invoke the handler */
                MUTEX_Unlock(&q->mutex);
                w->proc(w, w->param);
                MUTEX_Lock(&q->mutex);

                q->lastActivity = TIME_Now();
                if (w->flags & WKI_DETACHED) {
                
                    /* put the work item to the pool or deallocate it */
                    ASSERT(!w->waiters);
                    QUEUE_RemoveEntry(&w->itemsQ);
                    WKQ_ReleaseWorkItem(&WKQ, w);

                } else {

                    /* 
                     * update flags. Note that we released the mutex when 
                     * were invoking the callback. Therefore, this work 
                     * item could be re-submitted to the queue. Or it could
                     * be re-submitted and then canceled. In such cases we
                     * don't need to set the WKI_DONE flag.
                     */
                    w->flags &= ~WKI_CALL;
                    if (!(w->flags & WKI_CANCELED) && !w->submitQ.queue) {
                        w->flags |= WKI_DONE;
                    }

                    /* signal the events associated with the work item */
                    WKI_Signal(w);
                }
            } else {
                
                /* it's a dummy work item. Just release the waiters */
                WKI_Signal(w);
            }
        }

        /* wait for a signal */
        if (q->flags & WKQ_ACTIVE) {
            EVENT_Reset(&q->event);
            if (q->idleProc) {

                /* we have an idle timeout */
                IdleProc idle = q->idleProc;
                void * param = q->idleParam;
                Time now = TIME_Now();
                Time deadline = q->lastActivity + q->idleTimeout;
                if (deadline > now) {
                    MUTEX_Unlock(&q->mutex);
                    switch (EVENT_TimeWait(&q->event,(long)(deadline-now))) {

                    case WAIT_STATE_OK:
                        /* don't invoke idle callback */
                        MUTEX_Lock(&q->mutex);
                        break;

                    case WAIT_STATE_TIMEOUT:
                        /* invoke idle callback */
                        MUTEX_Lock(&q->mutex);
                        now = TIME_Now();
                        deadline = q->lastActivity + q->idleTimeout;
                        if (deadline <= now) {
                            MUTEX_Unlock(&q->mutex);
                            q->lastActivity = now;
                            idle(q, param);
                            MUTEX_Lock(&q->mutex);
                        }
                        break;

                    default:
                    case WAIT_STATE_ERROR:
                        /* terminate the thread on error */
                        MUTEX_Lock(&q->mutex);
                        q->flags &= ~WKQ_ACTIVE;
                        break;
                    }
                } else {
                    q->lastActivity = now;
                    MUTEX_Unlock(&q->mutex);
                    idle(q, param);
                    MUTEX_Lock(&q->mutex);
                }

            } else {

                /* wait forever */
                MUTEX_Unlock(&q->mutex);
                EVENT_Wait(&q->event);
                MUTEX_Lock(&q->mutex);
            }
        }
    }

    /* cleanup */
    MUTEX_Unlock(&q->mutex);
    TRACE("WKQ: done\n");
    if (q->flags & WKQ_KILLME) {
        TRACE1("WKQ: killing WorkQueue %p\n",q);
        WKQ_Free(q);
    }
}