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; } } }
enum pubnub_res pubnub_last_result(pubnub_t const *pb) { PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); if (pb->state != PBS_IDLE) { pbnc_fsm((pubnub_t*)pb); } return pb->core.last_result; }
enum pubnub_res pubnub_await(pubnub_t *pb) { PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); while (pb->state != PBS_IDLE) { pbnc_fsm(pb); } return pb->core.last_result; }
enum pubnub_res pubnub_await(pubnub_t *pb) { enum pubnub_res result; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pubnub_mutex_lock(pb->monitor); while (pb->state != PBS_IDLE) { pbnc_fsm(pb); } result = pb->core.last_result; pubnub_mutex_unlock(pb->monitor); return result; }
enum pubnub_res pubnub_last_result(pubnub_t* pb) { enum pubnub_res result; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pubnub_mutex_lock(pb->monitor); if (!pbnc_can_start_transaction(pb)) { pbnc_fsm((pubnub_t*)pb); } result = pb->core.last_result; pubnub_mutex_unlock(pb->monitor); return result; }
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); } }
enum pubnub_res pubnub_history(pubnub_t *pb, const char *channel, unsigned count, bool include_token) { enum pubnub_res rslt; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); if (pb->state != PBS_IDLE) { return PNR_IN_PROGRESS; } rslt = pbcc_history_prep(&pb->core, channel, count, include_token); if (PNR_STARTED == rslt) { pb->trans = PBTT_HISTORY; pb->core.last_result = PNR_STARTED; pbnc_fsm(pb); rslt = pb->core.last_result; } return rslt; }
enum pubnub_res pubnub_global_here_now(pubnub_t *pb) { enum pubnub_res rslt; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); if (pb->state != PBS_IDLE) { return PNR_IN_PROGRESS; } rslt = pbcc_here_now_prep(&pb->core, NULL, NULL); if (PNR_STARTED == rslt) { pb->trans = PBTT_GLOBAL_HERENOW; pb->core.last_result = PNR_STARTED; pbnc_fsm(pb); rslt = pb->core.last_result; } return rslt; }
enum pubnub_res pubnub_where_now(pubnub_t *pb, const char *uuid) { enum pubnub_res rslt; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); if (pb->state != PBS_IDLE) { return PNR_IN_PROGRESS; } rslt = pbcc_where_now_prep(&pb->core, uuid ? uuid : pb->core.uuid); if (PNR_STARTED == rslt) { pb->trans = PBTT_WHERENOW; pb->core.last_result = PNR_STARTED; pbnc_fsm(pb); rslt = pb->core.last_result; } return rslt; }
enum pubnub_res pubnub_time(pubnub_t *p) { enum pubnub_res rslt; PUBNUB_ASSERT(pb_valid_ctx_ptr(p)); if (p->state != PBS_IDLE) { return PNR_IN_PROGRESS; } rslt = pbcc_time_prep(&p->core); if (PNR_STARTED == rslt) { p->trans = PBTT_TIME; p->core.last_result = PNR_STARTED; pbnc_fsm(p); rslt = p->core.last_result; } return rslt; }
enum pubnub_res pubnub_subscribe(pubnub_t *p, const char *channel, const char *channel_group) { enum pubnub_res rslt; PUBNUB_ASSERT(pb_valid_ctx_ptr(p)); if (p->state != PBS_IDLE) { return PNR_IN_PROGRESS; } rslt = pbcc_subscribe_prep(&p->core, channel, channel_group); if (PNR_STARTED == rslt) { p->trans = PBTT_SUBSCRIBE; p->core.last_result = PNR_STARTED; pbnc_fsm(p); rslt = p->core.last_result; } return rslt; }
enum pubnub_res pubnub_publishv2(pubnub_t *pb, const char *channel, const char *message, bool store_in_history, bool eat_after_reading) { enum pubnub_res rslt; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); if (pb->state != PBS_IDLE) { return PNR_IN_PROGRESS; } rslt = pbcc_publish_prep(&pb->core, channel, message, store_in_history, eat_after_reading); if (PNR_STARTED == rslt) { pb->trans = PBTT_PUBLISH; pb->core.last_result = PNR_STARTED; pbnc_fsm(pb); rslt = pb->core.last_result; } return rslt; }
enum pubnub_res pubnub_list_channel_group(pubnub_t *pb, char const *channel_group) { enum pubnub_res rslt; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); if (pb->state != PBS_IDLE) { return PNR_IN_PROGRESS; } rslt = pbcc_channel_registry_prep(&pb->core, channel_group, NULL, NULL); if (PNR_STARTED == rslt) { pb->trans = PBTT_LIST_CHANNEL_GROUP; pb->core.last_result = PNR_STARTED; pbnc_fsm(pb); rslt = pb->core.last_result; } return rslt; }
enum pubnub_res pubnub_publish(pubnub_t *pb, const char *channel, const char *message) { enum pubnub_res rslt; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); if (pb->state != PBS_IDLE) { return PNR_IN_PROGRESS; } rslt = pbcc_publish_prep(&pb->core, channel, message, true, false); if (PNR_STARTED == rslt) { pb->trans = PBTT_PUBLISH; pb->core.last_result = PNR_STARTED; pbnc_fsm(pb); rslt = pb->core.last_result; } return rslt; }
enum pubnub_res pubnub_state_get(pubnub_t *pb, char const *channel, char const *channel_group, const char *uuid) { enum pubnub_res rslt; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); if (pb->state != PBS_IDLE) { return PNR_IN_PROGRESS; } rslt = pbcc_state_get_prep(&pb->core, channel, channel_group, uuid ? uuid : pb->core.uuid); if (PNR_STARTED == rslt) { pb->trans = PBTT_STATE_GET; pb->core.last_result = PNR_STARTED; pbnc_fsm(pb); rslt = pb->core.last_result; } return rslt; }
enum pubnub_res pubnub_add_channel_to_group(pubnub_t *pb, char const *channel, char const *channel_group) { enum pubnub_res rslt; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pubnub_mutex_lock(pb->monitor); if (pb->state != PBS_IDLE) { pubnub_mutex_unlock(pb->monitor); return PNR_IN_PROGRESS; } rslt = pbcc_channel_registry_prep(&pb->core, channel_group, "add", channel); if (PNR_STARTED == rslt) { pb->trans = PBTT_ADD_CHANNEL_TO_GROUP; pb->core.last_result = PNR_STARTED; pbnc_fsm(pb); rslt = pb->core.last_result; } pubnub_mutex_unlock(pb->monitor); return rslt; }
enum pubnub_res pubnub_set_state(pubnub_t *pb, char const *channel, char const *channel_group, const char *uuid, char const *state) { enum pubnub_res rslt; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pubnub_mutex_lock(pb->monitor); if (pb->state != PBS_IDLE) { pubnub_mutex_unlock(pb->monitor); return PNR_IN_PROGRESS; } rslt = pbcc_set_state_prep(&pb->core, channel, channel_group, uuid ? uuid : pb->core.uuid, state); if (PNR_STARTED == rslt) { pb->trans = PBTT_SET_STATE; pb->core.last_result = PNR_STARTED; pbnc_fsm(pb); rslt = pb->core.last_result; } pubnub_mutex_unlock(pb->monitor); return rslt; }
enum pubnub_res pubnub_here_now(pubnub_t *pb, const char *channel, const char *channel_group) { enum pubnub_res rslt; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pubnub_mutex_lock(pb->monitor); if (pb->state != PBS_IDLE) { pubnub_mutex_unlock(pb->monitor); return PNR_IN_PROGRESS; } rslt = pbcc_here_now_prep(&pb->core, channel, channel_group, pbccNotSet, pbccNotSet); if (PNR_STARTED == rslt) { pb->trans = PBTT_HERENOW; pb->core.last_result = PNR_STARTED; pbnc_fsm(pb); rslt = pb->core.last_result; } pubnub_mutex_unlock(pb->monitor); return rslt; }
enum pubnub_res pubnub_leave(pubnub_t *p, const char *channel, const char *channel_group) { enum pubnub_res rslt; PUBNUB_ASSERT(pb_valid_ctx_ptr(p)); pubnub_mutex_lock(p->monitor); if (p->state != PBS_IDLE) { pubnub_mutex_unlock(p->monitor); return PNR_IN_PROGRESS; } rslt = pbcc_leave_prep(&p->core, channel, channel_group); if (PNR_STARTED == rslt) { p->trans = PBTT_LEAVE; p->core.last_result = PNR_STARTED; pbnc_fsm(p); rslt = p->core.last_result; } pubnub_mutex_unlock(p->monitor); return rslt; }
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); } }