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_set_uuid(pubnub_t *pb, const char *uuid) { PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pubnub_mutex_lock(pb->monitor); pbcc_set_uuid(&pb->core, uuid); pubnub_mutex_unlock(pb->monitor); }
pubnub_t* pubnub_init(pubnub_t *p, const char *publish_key, const char *subscribe_key) { PUBNUB_ASSERT(pb_valid_ctx_ptr(p)); pubnub_mutex_init(p->monitor); pubnub_mutex_lock(p->monitor); pbcc_init(&p->core, publish_key, subscribe_key); if (PUBNUB_TIMERS_API) { p->transaction_timeout_ms = PUBNUB_DEFAULT_TRANSACTION_TIMER; #if defined(PUBNUB_DEFAULT_CONNECTION_TIMER) p->connection_timeout_s = PUBNUB_DEFAULT_CONNECTION_TIMER; #endif #if defined(PUBNUB_CALLBACK_API) p->previous = p->next = NULL; #endif } #if defined(PUBNUB_CALLBACK_API) p->cb = NULL; p->user_data = NULL; #endif if (PUBNUB_ORIGIN_SETTABLE) { p->origin = PUBNUB_ORIGIN; } p->state = PBS_IDLE; p->trans = PBTT_NONE; pbpal_init(p); pubnub_mutex_unlock(p->monitor); return p; }
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; }
static void sublup_context_callback(pubnub_t* pb, enum pubnub_trans trans, enum pubnub_res result, void* user_data) { pubnub_subloop_t* pbsld = (pubnub_subloop_t*)user_data; PUBNUB_ASSERT_OPT(pbsld != NULL); pubnub_mutex_lock(pbsld->monitor); if (PBTT_SUBSCRIBE == trans) { if (PNR_OK == result) { char const* msg; for (msg = pubnub_get(pb); msg != NULL; msg = pubnub_get(pb)) { pbsld->cb(pb, msg, PNR_OK); } } else { pbsld->cb(pb, NULL, result); } result = pubnub_subscribe_ex(pbsld->pbp, pbsld->channel, pbsld->options); if (result != PNR_STARTED) { PUBNUB_LOG_ERROR("Failed to re-subscribe in the subscribe loop, " "error code = %d\n", result); } } pubnub_mutex_unlock(pbsld->monitor); }
void pubnub_set_auth(pubnub_t *pb, const char *auth) { PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pubnub_mutex_lock(pb->monitor); pbcc_set_auth(&pb->core, auth); pubnub_mutex_unlock(pb->monitor); }
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); }
int pubnub_last_http_code(pubnub_t *pb) { int result; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pubnub_mutex_lock(pb->monitor); result = pb->http_code; pubnub_mutex_unlock(pb->monitor); return result; }
char const *pubnub_last_time_token(pubnub_t *pb) { char const *result; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pubnub_mutex_lock(pb->monitor); result = pb->core.timetoken; pubnub_mutex_unlock(pb->monitor); return result; }
char const *pubnub_get(pubnub_t *pb) { char const *result; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pubnub_mutex_lock(pb->monitor); result = pbcc_get_msg(&pb->core); pubnub_mutex_unlock(pb->monitor); return result; }
void pnc_ops_unsubscribe(pubnub_t *pn_sub) { pubnub_mutex_lock(m_loop_enabled_mutex); if (m_loop_enabled) { m_loop_enabled = false; puts("Subscription loop is disabled and will be stopped after the next message received."); } else { puts("Subscription loop is already disabled."); } pubnub_mutex_unlock(m_loop_enabled_mutex); }
char const *pubnub_last_publish_result(pubnub_t *pb) { char *end; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pubnub_mutex_lock(pb->monitor); if (PUBNUB_DYNAMIC_REPLY_BUFFER && (NULL == pb->core.http_reply)) { pubnub_mutex_unlock(pb->monitor); return ""; } if ((pb->trans != PBTT_PUBLISH) || (pb->core.http_reply[0] == '\0')) { pubnub_mutex_unlock(pb->monitor); return ""; } for (end = pb->core.http_reply + 1; isdigit((unsigned)*end); ++end) { continue; } pubnub_mutex_unlock(pb->monitor); return end + 1; }
void pubnub_subloop_stop(pubnub_subloop_t* pbsld) { PUBNUB_ASSERT_OPT(NULL != pbsld); pubnub_mutex_lock(pbsld->monitor); PUBNUB_ASSERT_OPT(NULL != pbsld->pbp); pubnub_register_callback( pbsld->pbp, pbsld->saved_context_cb, pbsld->saved_context_user_data); pubnub_cancel(pbsld->pbp); pbsld->saved_context_cb = NULL; pbsld->saved_context_user_data = NULL; pubnub_mutex_unlock(pbsld->monitor); }
void pballoc_free_at_last(pubnub_t* pb) { PUBNUB_LOG_TRACE("pballoc_free_at_last(%p)\n", pb); PUBNUB_ASSERT_OPT(pb != NULL); PUBNUB_LOG_TRACE("pubnub_free_at_last(%p)\n", pb); pubnub_mutex_lock(pb->monitor); pubnub_mutex_init_static(m_lock); pubnub_mutex_lock(m_lock); PUBNUB_ASSERT_OPT(pb->state == PBS_NULL); pbcc_deinit(&pb->core); pbpal_free(pb); remove_allocated(pb); pubnub_mutex_unlock(pb->monitor); pubnub_mutex_destroy(pb->monitor); pubnub_mutex_unlock(m_lock); free(pb); }
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; }
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; }
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)); 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, 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; } pubnub_mutex_unlock(pb->monitor); return rslt; }
char const *pubnub_get_origin(pubnub_t *pb) { PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); if (PUBNUB_ORIGIN_SETTABLE) { char const *result; pubnub_mutex_lock(pb->monitor); result = pb->origin; pubnub_mutex_unlock(pb->monitor); return result; } return PUBNUB_ORIGIN; }
enum pubnub_res pubnub_time(pubnub_t *p) { 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_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; } pubnub_mutex_unlock(p->monitor); return rslt; }
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)); pubnub_mutex_lock(pb->monitor); if (pb->state != PBS_IDLE) { pubnub_mutex_unlock(pb->monitor); 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; } pubnub_mutex_unlock(pb->monitor); return rslt; }
enum pubnub_res pubnub_heartbeat(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_heartbeat_prep(&pb->core, channel, channel_group); if (PNR_STARTED == rslt) { pb->trans = PBTT_HEARTBEAT; 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_global_here_now(pubnub_t *pb) { 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, NULL, NULL, pbccNotSet, pbccNotSet); if (PNR_STARTED == rslt) { pb->trans = PBTT_GLOBAL_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_where_now(pubnub_t *pb, const char *uuid) { 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_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; } pubnub_mutex_unlock(pb->monitor); return rslt; }
enum pubnub_res pubnub_set_secret_key(pubnub_t *p, char const* secret_key) { PUBNUB_ASSERT_OPT(p != NULL); #if PUBNUB_CRYPTO_API pubnub_mutex_lock(p->monitor); p->core.secret_key = secret_key; pubnub_mutex_unlock(p->monitor); return PNR_OK; #else return PNR_CRYPTO_NOT_SUPPORTED; #endif }
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)); pubnub_mutex_lock(pb->monitor); if (pb->state != PBS_IDLE) { pubnub_mutex_unlock(pb->monitor); 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; } pubnub_mutex_unlock(pb->monitor); 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)); pubnub_mutex_lock(pb->monitor); if (pb->state != PBS_IDLE) { pubnub_mutex_unlock(pb->monitor); 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; } pubnub_mutex_unlock(pb->monitor); return rslt; }
static void save_allocated(pubnub_t* pb) { #if defined PUBNUB_ASSERT_LEVEL_EX pubnub_mutex_init_static(m_lock); pubnub_mutex_lock(m_lock); if (m_n == m_cap) { pubnub_t** npalloc = (pubnub_t**)realloc(m_allocated, sizeof m_allocated[0] * (m_n + 1)); if (NULL == npalloc) { PUBNUB_LOG_WARNING("Couldn't allocate memory for pubnub_alloc_std bookkeeping"); pubnub_mutex_unlock(m_lock); return; } m_allocated = npalloc; m_allocated[m_n++] = pb; m_cap = m_n; } else { m_allocated[m_n++] = pb; } pubnub_mutex_unlock(m_lock); #endif }
bool pb_valid_ctx_ptr(pubnub_t const* pb) { #if defined PUBNUB_ASSERT_LEVEL_EX bool result; pubnub_mutex_init_static(m_lock); pubnub_mutex_lock(m_lock); result = check_ctx_ptr(pb); pubnub_mutex_unlock(m_lock); return result; #else return pb != NULL; #endif }
void pubnub_subloop_undef(pubnub_subloop_t* pbsld) { PUBNUB_ASSERT_OPT(NULL != pbsld); pubnub_mutex_lock(pbsld->monitor); if (sublup_context_callback == pubnub_get_callback(pbsld->pbp)) { pubnub_register_callback( pbsld->pbp, pbsld->saved_context_cb, pbsld->saved_context_user_data); pubnub_cancel(pbsld->pbp); } pbsld->pbp = NULL; pubnub_mutex_unlock(pbsld->monitor); pubnub_mutex_destroy(pbsld->monitor); free(pbsld); }