bool as_event_send_close_loop(as_event_loop* event_loop) { // Send stop command through queue so it can be executed in event loop thread. pthread_mutex_lock(&event_loop->lock); as_uv_command qcmd = {.type = AS_UV_EXIT_LOOP, .ptr = 0}; bool queued = as_queue_push(&event_loop->queue, &qcmd); pthread_mutex_unlock(&event_loop->lock); if (queued) { uv_async_send(event_loop->wakeup); } return queued; } void as_event_close_loop(as_event_loop* event_loop) { uv_close((uv_handle_t*)event_loop->wakeup, as_uv_wakeup_closed); // Only stop event loop if client created event loop. if (as_event_threads_created) { uv_stop(event_loop->loop); } // Cleanup event loop resources. as_queue_destroy(&event_loop->queue); as_queue_destroy(&event_loop->pipe_cb_queue); pthread_mutex_unlock(&event_loop->lock); pthread_mutex_destroy(&event_loop->lock); }
static bool as_uv_queue_close_connections(as_node* node, as_queue* conn_queue, as_queue* cmd_queue) { as_uv_command qcmd; qcmd.type = AS_UV_CLOSE_CONNECTION; as_event_connection* conn; // Queue connection commands to event loops. while (as_queue_pop(conn_queue, &conn)) { qcmd.ptr = conn; if (! as_queue_push(cmd_queue, &qcmd)) { as_log_error("Failed to queue connection close"); return false; } // In this case, connection counts are decremented before the connection is closed. // This is done because the node will be invalid when the deferred connection close occurs. // Since node destroy always waits till there are no node references, all transactions that // referenced this node should be completed by the time this code is executed. as_event_decr_connection(node->cluster, conn_queue); ck_pr_dec_32(&node->cluster->async_conn_pool); } return true; }
static inline void as_event_put_connection(as_event_command* cmd) { as_queue* queue = &cmd->node->async_conn_qs[cmd->event_loop->index]; if (as_queue_push(queue, &cmd->conn)) { ck_pr_inc_32(&cmd->cluster->async_conn_pool); } else { as_event_release_connection(cmd->cluster, cmd->conn, queue); } }
bool as_event_send_close_loop(as_event_loop* event_loop) { // Send stop command through queue so it can be executed in event loop thread. void* ptr = 0; pthread_mutex_lock(&event_loop->lock); bool queued = as_queue_push(&event_loop->queue, &ptr); pthread_mutex_unlock(&event_loop->lock); if (queued) { ev_async_send(event_loop->loop, &event_loop->wakeup); } return queued; }
bool as_event_send(as_event_command* cmd) { // Notify other event loop thread that queue needs to be processed. as_event_loop* event_loop = cmd->event_loop; pthread_mutex_lock(&event_loop->lock); bool queued = as_queue_push(&event_loop->queue, &cmd); pthread_mutex_unlock(&event_loop->lock); if (queued) { ev_async_send(event_loop->loop, &event_loop->wakeup); } return queued; }
bool as_event_send(as_event_command* cmd) { // Send command through queue so it can be executed in event loop thread. as_event_loop* event_loop = cmd->event_loop; pthread_mutex_lock(&event_loop->lock); as_uv_command qcmd = {.type = AS_UV_PROCESS_COMMAND, .ptr = cmd}; bool queued = as_queue_push(&event_loop->queue, &qcmd); pthread_mutex_unlock(&event_loop->lock); if (queued) { uv_async_send(event_loop->wakeup); } return queued; }