void * rut_memory_stack_alloc (RutMemoryStack *stack, size_t bytes) { RutMemorySubStack *sub_stack; void *ret; sub_stack = stack->sub_stack; if (G_LIKELY (sub_stack->bytes - stack->sub_stack_offset >= bytes)) { ret = sub_stack->data + stack->sub_stack_offset; stack->sub_stack_offset += bytes; return ret; } /* If the stack has been rewound and then a large initial allocation * is made then we may need to skip over one or more of the * sub-stacks that are too small for the requested allocation * size... * * XXX: note we don't use rut_list_for_each here because we need to be * careful to iterate the list starting from our current position, but * stopping if we loop back to the first sub_stack. (NB: A RutList * is a circular list) */ for (sub_stack = rut_container_of (stack->sub_stack->list_node.next, sub_stack, list_node); &sub_stack->list_node != &stack->sub_stacks; sub_stack = rut_container_of (sub_stack->list_node.next, sub_stack, list_node)) { if (sub_stack->bytes >= bytes) { ret = sub_stack->data; stack->sub_stack = sub_stack; stack->sub_stack_offset = bytes; return ret; } } /* Finally if we couldn't find a free sub-stack with enough space * for the requested allocation we allocate another sub-stack that's * twice as big as the last sub-stack or twice as big as the * requested allocation if that's bigger. */ sub_stack = rut_container_of (stack->sub_stacks.prev, sub_stack, list_node); rut_memory_stack_add_sub_stack (stack, MAX (sub_stack->bytes, bytes) * 2); sub_stack = rut_container_of (stack->sub_stacks.prev, sub_stack, list_node); stack->sub_stack_offset += bytes; return sub_stack->data; }
void rut_memory_stack_rewind (RutMemoryStack *stack) { stack->sub_stack = rut_container_of (stack->sub_stacks.next, stack->sub_stack, list_node); stack->sub_stack_offset = 0; }
static void on_address_resolved(uv_getaddrinfo_t *resolver, int status, struct addrinfo *result) { rig_pb_stream_t *stream = rut_container_of(resolver, stream, resolver); uv_loop_t *loop = rut_uv_shell_get_loop(stream->shell); char ip_address[17] = {'\0'}; c_return_if_fail(stream->resolving); if (status < 0) { c_warning("Failed to resolve slave address \"%s\": %s", stream->hostname, uv_strerror(status)); rut_closure_list_invoke(&stream->on_error_closures, rig_pb_stream_callback_t, stream); /* NB: we were at least keeping the stream alive while * waiting for the resolve request to finish... */ stream->resolving = false; rut_object_unref(stream); return; } uv_ip4_name((struct sockaddr_in*)result->ai_addr, ip_address, 16); c_message("stream: Resolved address of \"%s\" = %s", stream->hostname, ip_address); uv_tcp_init(loop, &stream->tcp.socket); stream->tcp.socket.data = stream; /* NB: we took a reference to keep the stream alive while * resolving the address, so conceptually we are now handing * the reference over to keep the stream alive while waiting * for it to connect... */ stream->resolving = false; stream->connecting = true; stream->connection_request.data = stream; uv_tcp_connect(&stream->connection_request, &stream->tcp.socket, result->ai_addr, on_connect); uv_freeaddrinfo(result); }