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; }
static void* reconn_fun(void* arg){ conn_t* conn; queue_t* q = &g_ctx.reconn_q; rval_t rval; int times = 1; while(1){ conn = list_entry(deque(q), conn_t, reconn_link); assert(conn->conn_state == CONNECTING); assert(conn->conn_type == ACTIVE); debug_info("start reconn conn[%d], fd[%d],%s \n", conn->id, conn->sockfd, dump_addr(conn->addr)); rval = re_connect(conn); if(success(rval)){ debug_info("reconn conn[%d], fd[%d] success! \n", conn->id, conn->sockfd); set_conn_state(conn, CONNECTED); add_event(conn); }else{ debug_warn("reconn conn[%d], fd[%d] failed! errno[%d]\n", conn->id, conn->sockfd, rval.err); enque(q, &conn->reconn_link); //continue reconn } sleep(times); } }
/* * Callback functions */ void connect_cb(GIOChannel *io, GError *err, gpointer user_data) { printf_dbg("[CB] IN connect_cb\n"); if (err) { set_conn_state(STATE_DISCONNECTED); cb_ret_val = BL_REQUEST_FAIL_ERROR; sprintf(cb_ret_msg, "%s", err->message); goto error; } attrib = g_attrib_new(iochannel); set_conn_state(STATE_CONNECTED); strcpy(cb_ret_msg, "Connection successful\n"); cb_ret_val = BL_NO_ERROR; error: g_mutex_unlock(pending_callback); printf_dbg("[CB] OUT connect_cb\n"); }
/* * Callback functions */ void connect_cb(GIOChannel *io, GError *err, gpointer user_data) { cb_ctx_t *cb_ctx = user_data; printf_dbg("IN connect_cb\n"); if (err) { set_conn_state(cb_ctx->dev_ctx, STATE_DISCONNECTED); cb_ctx->cb_ret_val = BL_REQUEST_FAIL_ERROR; sprintf(cb_ctx->cb_ret_msg, "%s", err->message); goto error; } cb_ctx->dev_ctx->attrib = g_attrib_new(cb_ctx->dev_ctx->iochannel); set_conn_state(cb_ctx->dev_ctx, STATE_CONNECTED); strcpy(cb_ctx->cb_ret_msg, "Connection successful\n"); cb_ctx->cb_ret_val = BL_NO_ERROR; error: g_mutex_unlock(&cb_ctx->pending_cb_mtx); printf_dbg("OUT connect_cb\n"); }
static int tcp_timer_routine( void *param) { struct tcp_conn *conn; struct tcp_conn *cnext; int now; int h; now = get_ticks(); for( h=0 ; h<TCP_HASH_SIZE ; h++) { lock_get( &hash_id_lock ); for( conn=hash_id_conns[h]; conn ; conn=cnext ) { cnext = conn->id_next; /* check connection timeout */ if (conn->timeout<=now) { /* timeout on connection activity -> if connection is valid, * fire the OUT reactor to resume (with error) the write * context and the IN reactor to stop the read operation */ conn->timeout = 0; if ( set_conn_state(conn, TCP_CONN_TERM)!=-1 ) { LM_DBG("Terminating conn %p (%d) (time=%d)\n", conn,conn->socket,now); conn->ref++; break; } } } lock_release( &hash_id_lock ); if (conn) { /* fire OUT reactor */ fire_fd( reactor_out, conn->socket); /* fire IN reactor */ fire_fd( reactor_in, conn->socket); remove_tcp_conn(conn, 1); /* force checking again the same hash */ h--; } } return 0; }