예제 #1
0
enum pubnub_res pubnub_await(pubnub_t* pb)
{
    pbmsref_t       t0;
    enum pubnub_res result;
    bool            stopped = false;

    PUBNUB_ASSERT(pb_valid_ctx_ptr(pb));

    pubnub_mutex_lock(pb->monitor);
    t0 = pbms_start();
    while (!pbnc_can_start_transaction(pb)) {
        pbms_t delta;

        pbnc_fsm(pb);

        delta = pbms_elapsed(t0);
        if (delta > pb->transaction_timeout_ms) {
            if (!stopped) {
                pbnc_stop(pb, PNR_TIMEOUT);
                t0      = pbms_start();
                stopped = true;
            }
            else {
                break;
            }
        }
    }
    result = pb->core.last_result;
    pubnub_mutex_unlock(pb->monitor);

    return result;
}
예제 #2
0
void pubnub_task(void)
{
    static uint32_t s_tick_prev;

    if (0 == s_tick_prev) {
        s_tick_prev = SYS_TMR_TickCountGet();
    }
    
    if (m_watcher.apb_size > 0) {
        pubnub_t **ppbp;
        uint32_t tick_now = SYS_TMR_TickCountGet();
        int elapsed = elapsed_ms(s_tick_prev, tick_now);

        for (ppbp = m_watcher.apb; ppbp < m_watcher.apb + m_watcher.apb_size; ++ppbp) {
            pbnc_fsm(*ppbp);
        }
        if (elapsed > 0) {
            pubnub_t *expired = pubnub_timer_list_as_time_goes_by(&m_watcher.timer_head, elapsed);
            while (expired != NULL) {
                pubnub_t *next = expired->next;

                pbnc_stop(expired, PNR_TIMEOUT);

                expired->previous = NULL;
                expired->next = NULL;
                expired = next;
            }
            s_tick_prev = tick_now;
        }
    }
}
예제 #3
0
int pubnub_free(pubnub_t* pb)
{
    int result = -1;

    PUBNUB_ASSERT(check_ctx_ptr(pb));

    PUBNUB_LOG_TRACE("pubnub_free(%p)\n", pb);

    pubnub_mutex_lock(pb->monitor);
    pbnc_stop(pb, PNR_CANCELLED);
    if (PBS_IDLE == pb->state) {
        PUBNUB_LOG_TRACE("pubnub_free(%p) PBS_IDLE\n", pb);
        pb->state = PBS_NULL;
#if defined(PUBNUB_CALLBACK_API)
        pbntf_requeue_for_processing(pb);
        pubnub_mutex_unlock(pb->monitor);
#else
        pubnub_mutex_unlock(pb->monitor);
        pballoc_free_at_last(pb);
#endif

        result = 0;
    }
    else {
        PUBNUB_LOG_TRACE("pubnub_free(%p) pb->state=%d\n", pb, pb->state);
        pubnub_mutex_unlock(pb->monitor);
    }

    return result;
}
예제 #4
0
void pubnub_cancel(pubnub_t *pb)
{
    PUBNUB_ASSERT(pb_valid_ctx_ptr(pb));

    pubnub_mutex_lock(pb->monitor);
    pbnc_stop(pb, PNR_CANCELLED);
    pubnub_mutex_unlock(pb->monitor);
}
void socket_watcher_task(void *arg)
{
    TickType_t xTimePrev = xTaskGetTickCount();
    struct SocketWatcherData *pWatcher = (struct SocketWatcherData *)arg;

    for (;;) {

        ulTaskNotifyTake(pdTRUE, TICKS_TO_WAIT);

        if (pdFALSE == xSemaphoreTakeRecursive(m_watcher.mutw, TICKS_TO_WAIT)) {
            continue;
        }

        if (pWatcher->apb_size > 0) {
            if (FreeRTOS_select(pWatcher->xFD_set, TICKS_TO_WAIT) != 0) {
                pubnub_t **ppbp;
                for (ppbp = pWatcher->apb; ppbp < pWatcher->apb + pWatcher->apb_size; ++ppbp) {
                    if (FreeRTOS_FD_ISSET((*ppbp)->pal.socket, pWatcher->xFD_set)) {
                        pbnc_fsm(*ppbp);
                    }
                }
            }
        }

        if (PUBNUB_TIMERS_API) {
            TickType_t xTimeNow = xTaskGetTickCount();
            int elapsed = elapsed_ms(xTimePrev, xTimeNow);
            if (elapsed > 0) {
                pubnub_t *expired = pubnub_timer_list_as_time_goes_by(&m_watcher.timer_head, elapsed);
                while (expired != NULL) {
                    pubnub_t *next = expired->next;
                    
                    pbnc_stop(expired, PNR_TIMEOUT);
                    
                    expired->previous = NULL;
                    expired->next = NULL;
                    expired = next;
                }
                xTimePrev = xTimeNow;
            }
        }

        xSemaphoreGiveRecursive(m_watcher.mutw);
    }
}
void socket_watcher_thread(void *arg)
{
    FILETIME prev_time;
    GetSystemTimeAsFileTime(&prev_time);

    for (;;) {
        const DWORD ms = 100;

        EnterCriticalSection(&m_watcher.queue_lock);
        if (m_watcher.queue_head != m_watcher.queue_tail) {
            pubnub_t *pbp = m_watcher.queue_apb[m_watcher.queue_tail++];
            LeaveCriticalSection(&m_watcher.queue_lock);
            if (pbp != NULL) {
                pubnub_mutex_lock(pbp->monitor);
                pbnc_fsm(pbp);
                pubnub_mutex_unlock(pbp->monitor);
            }
            EnterCriticalSection(&m_watcher.queue_lock);
            if (m_watcher.queue_tail == m_watcher.queue_size) {
                m_watcher.queue_tail = 0;
            }
        }
        LeaveCriticalSection(&m_watcher.queue_lock);

        EnterCriticalSection(&m_watcher.mutw);
        if (0 == m_watcher.apoll_size) {
            LeaveCriticalSection(&m_watcher.mutw);
            continue;
        }
        {
            int rslt = WSAPoll(m_watcher.apoll, m_watcher.apoll_size, ms);
            if (SOCKET_ERROR == rslt) {
                /* error? what to do about it? */
                PUBNUB_LOG_WARNING("poll size = %d, error = %d\n", m_watcher.apoll_size, WSAGetLastError());
            }
            else if (rslt > 0) {
                size_t i;
                size_t apoll_size = m_watcher.apoll_size;
                for (i = 0; i < apoll_size; ++i) {
                    if (m_watcher.apoll[i].revents & (POLLIN | POLLOUT)) {
                        pubnub_t *pbp = m_watcher.apb[i];
                        pubnub_mutex_lock(pbp->monitor);
                        pbnc_fsm(pbp);
                        if (apoll_size == m_watcher.apoll_size) {
                            if (m_watcher.apoll[i].events == POLLOUT) {
                                if ((pbp->state == PBS_WAIT_DNS_RCV) ||
                                    (pbp->state >= PBS_RX_HTTP_VER)) {
                                    m_watcher.apoll[i].events = POLLIN;
                                }
                            }
                            else {
                                if ((pbp->state > PBS_WAIT_DNS_RCV) &&
                                    (pbp->state < PBS_RX_HTTP_VER)) {
                                    m_watcher.apoll[i].events = POLLOUT;
                                }
                            }
                        }
                        else {
                            PUBNUB_ASSERT_OPT(apoll_size == m_watcher.apoll_size + 1);
                            apoll_size = m_watcher.apoll_size;
                            --i;
                        }
                        pubnub_mutex_unlock(pbp->monitor);
                    }
                }
            }
        }
        if (PUBNUB_TIMERS_API) {
            FILETIME current_time;
            int elapsed;
            GetSystemTimeAsFileTime(&current_time);
            elapsed = elapsed_ms(prev_time, current_time);
            if (elapsed > 0) {
                pubnub_t *expired = pubnub_timer_list_as_time_goes_by(&m_watcher.timer_head, elapsed);
                while (expired != NULL) {
                    pubnub_t *next = expired->next;

                    pubnub_mutex_lock(expired->monitor);
                    pbnc_stop(expired, PNR_TIMEOUT);
                    pubnub_mutex_unlock(expired->monitor);

                    expired->next = NULL;
                    expired->previous = NULL;
                    expired = next;
                }
                prev_time = current_time;
            }
        }

        LeaveCriticalSection(&m_watcher.mutw);
    }
}
예제 #7
0
void pubnub_cancel(pubnub_t *pb)
{
    PUBNUB_ASSERT(pb_valid_ctx_ptr(pb));

    pbnc_stop(pb, PNR_CANCELLED);
}