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; }
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; } } }
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; }
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(¤t_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); } }
void pubnub_cancel(pubnub_t *pb) { PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pbnc_stop(pb, PNR_CANCELLED); }