int wait_for_cb(cb_ctx_t *cb_ctx, void **ret_pointer, GError **gerr) { int wait_cnt = 0; if (!g_mutex_trylock(&cb_ctx->pending_cb_mtx) && is_event_loop_running()) { // Reset return value cb_ctx->cb_ret_val = BL_NO_CALLBACK_ERROR; cb_ctx->cb_ret_pointer = NULL; printf_dbg("Waiting for callback\n"); while (is_event_loop_running() && !g_mutex_trylock(&cb_ctx->pending_cb_mtx)) { usleep(100000); if (wait_cnt < CB_TIMEOUT_S*10) { wait_cnt++; } else { GError *err = g_error_new(BL_ERROR_DOMAIN, BL_NO_CALLBACK_ERROR, "Timeout no callback received\n"); printf_dbg("%s", err->message); PROPAGATE_ERROR; set_conn_state(cb_ctx->dev_ctx, STATE_DISCONNECTED); return BL_NO_CALLBACK_ERROR; } } } if (!is_event_loop_running()) { set_conn_state(cb_ctx->dev_ctx, STATE_DISCONNECTED); GError *err = g_error_new(BL_ERROR_DOMAIN, BL_DISCONNECTED_ERROR, "Event loop is not running\n"); printf_dbg("%s", err->message); PROPAGATE_ERROR; return BL_DISCONNECTED_ERROR; } else printf_dbg("Callback returned <%d, %p>\n", cb_ctx->cb_ret_val, cb_ctx->cb_ret_pointer); if (cb_ctx->cb_ret_val != BL_NO_ERROR) { GError *err = g_error_new(BL_ERROR_DOMAIN, cb_ctx->cb_ret_val, "%s", cb_ctx->cb_ret_msg); PROPAGATE_ERROR; } if (*cb_ctx->cb_ret_msg != '\0') { printf_dbg("%s", cb_ctx->cb_ret_msg); } strcpy(cb_ctx->cb_ret_msg, "\0"); if (ret_pointer) *ret_pointer = cb_ctx->cb_ret_pointer; return cb_ctx->cb_ret_val; }
int start_event_loop(GError **gerr) { pending_callback = malloc(sizeof(GMutex)); if (pending_callback == NULL) { GError *err = g_error_new(BL_ERROR_DOMAIN, BL_MALLOC_ERROR, "Start event loop: Malloc error\n"); PROPAGATE_ERROR; goto error1; } g_mutex_init(pending_callback); g_mutex_lock(pending_callback); cb_mutex = malloc(sizeof(GMutex)); if (cb_mutex == NULL) { GError *err = g_error_new(BL_ERROR_DOMAIN, BL_MALLOC_ERROR, "Start event loop: Malloc error\n"); PROPAGATE_ERROR; goto error2; } g_mutex_init(cb_mutex); event_thread = g_thread_try_new("event_loop", _event_thread, NULL, gerr); for (int cnt = 0; (!is_event_loop_running()) && (cnt < 60) && (event_thread != NULL) && (get_conn_state() == STATE_CONNECTING); cnt++) { sleep(1); printf_dbg("wait for event loop\n"); } if (event_thread == NULL) { printf_dbg("%s\n", (*gerr)->message); goto error3; } return 0; error3: free(cb_mutex); cb_mutex = NULL; error2: free(pending_callback); pending_callback = NULL; error1: return -1; }
int start_event_loop(GError **gerr) { g_mutex_init(&cb_mutex); event_thread = g_thread_try_new("event_loop", _event_thread, NULL, gerr); for (int cnt = 0; (!is_event_loop_running()) && (cnt < 60) && (event_thread != NULL); cnt++) { sleep(1); printf_dbg("wait for event loop\n"); } if (event_thread == NULL) { printf_dbg("%s\n", (*gerr)->message); goto error; } return 0; error: return -1; }