static void init_host_config(h2o_host_configuration_t *host_config) { h2o_linklist_init_anchor(&host_config->handlers); h2o_linklist_init_anchor(&host_config->filters); h2o_linklist_init_anchor(&host_config->loggers); h2o_register_chunked_filter(host_config); h2o_init_mimemap(&host_config->mimemap, H2O_DEFAULT_MIMETYPE); }
static void queue_init(h2o_http2_scheduler_queue_t *queue) { size_t i; queue->bits = 0; queue->offset = 0; for (i = 0; i != sizeof(queue->anchors) / sizeof(queue->anchors[0]); ++i) h2o_linklist_init_anchor(queue->anchors + i); h2o_linklist_init_anchor(&queue->anchor257); }
void h2o_config_init(h2o_global_configuration_t *config) { memset(config, 0, sizeof(*config)); h2o_linklist_init_anchor(&config->virtual_hosts); init_host_config(&config->default_host); h2o_linklist_init_anchor(&config->global_configurators); h2o_linklist_init_anchor(&config->host_configurators); config->server_name = h2o_buf_init(H2O_STRLIT("h2o/0.1")); config->req_timeout = H2O_DEFAULT_REQ_TIMEOUT; config->max_request_entity_size = H2O_DEFAULT_MAX_REQUEST_ENTITY_SIZE; config->http1_upgrade_to_http2 = H2O_DEFAULT_HTTP1_UPGRADE_TO_HTTP2; config->http2_max_concurrent_requests_per_connection = H2O_DEFAULT_HTTP2_MAX_CONCURRENT_REQUESTS_PER_CONNECTION; }
h2o_socketpool_target_t *h2o_socketpool_create_target(h2o_url_t *origin, h2o_socketpool_target_conf_t *lb_target_conf) { struct sockaddr_storage sa; socklen_t salen; h2o_socketpool_target_t *target = h2o_mem_alloc(sizeof(*target)); h2o_url_copy(NULL, &target->url, origin); assert(target->url.host.base[target->url.host.len] == '\0'); /* needs to be null-terminated in order to be used in SNI */ target->type = detect_target_type(origin, &sa, &salen); if (!(target->type == H2O_SOCKETPOOL_TYPE_SOCKADDR && sa.ss_family == AF_UNIX)) { h2o_strtolower(target->url.authority.base, target->url.authority.len); h2o_strtolower(target->url.host.base, target->url.host.len); } switch (target->type) { case H2O_SOCKETPOOL_TYPE_NAMED: target->peer.named_serv.base = h2o_mem_alloc(sizeof(H2O_UINT16_LONGEST_STR)); target->peer.named_serv.len = sprintf(target->peer.named_serv.base, "%u", (unsigned)h2o_url_get_port(&target->url)); break; case H2O_SOCKETPOOL_TYPE_SOCKADDR: assert(salen <= sizeof(target->peer.sockaddr.bytes)); memcpy(&target->peer.sockaddr.bytes, &sa, salen); target->peer.sockaddr.len = salen; break; } target->_shared.leased_count = 0; if (lb_target_conf != NULL) target->conf.weight_m1 = lb_target_conf->weight_m1; else { target->conf.weight_m1 = 0; } h2o_linklist_init_anchor(&target->_shared.sockets); return target; }
void h2o_config_init(h2o_globalconf_t *config) { memset(config, 0, sizeof(*config)); config->hosts = h2o_mem_alloc(sizeof(config->hosts[0])); config->hosts[0] = NULL; h2o_linklist_init_anchor(&config->configurators); config->server_name = h2o_iovec_init(H2O_STRLIT("h2o/" H2O_VERSION)); config->max_request_entity_size = H2O_DEFAULT_MAX_REQUEST_ENTITY_SIZE; config->max_delegations = H2O_DEFAULT_MAX_DELEGATIONS; config->handshake_timeout = H2O_DEFAULT_HANDSHAKE_TIMEOUT; config->http1.req_timeout = H2O_DEFAULT_HTTP1_REQ_TIMEOUT; config->http1.upgrade_to_http2 = H2O_DEFAULT_HTTP1_UPGRADE_TO_HTTP2; config->http1.callbacks = H2O_HTTP1_CALLBACKS; config->http2.idle_timeout = H2O_DEFAULT_HTTP2_IDLE_TIMEOUT; config->http2.graceful_shutdown_timeout = H2O_DEFAULT_HTTP2_GRACEFUL_SHUTDOWN_TIMEOUT; config->proxy.io_timeout = H2O_DEFAULT_PROXY_IO_TIMEOUT; config->proxy.connect_timeout = H2O_DEFAULT_PROXY_IO_TIMEOUT; config->proxy.first_byte_timeout = H2O_DEFAULT_PROXY_IO_TIMEOUT; config->proxy.emit_x_forwarded_headers = 1; config->proxy.emit_via_header = 1; config->proxy.emit_missing_date_header = 1; config->http2.max_concurrent_requests_per_connection = H2O_HTTP2_SETTINGS_HOST_MAX_CONCURRENT_STREAMS; config->http2.max_streams_for_priority = 16; config->http2.active_stream_window_size = H2O_DEFAULT_HTTP2_ACTIVE_STREAM_WINDOW_SIZE; config->http2.latency_optimization.min_rtt = 50; // milliseconds config->http2.latency_optimization.max_additional_delay = 10; config->http2.latency_optimization.max_cwnd = 65535; config->http2.callbacks = H2O_HTTP2_CALLBACKS; config->send_informational_mode = H2O_SEND_INFORMATIONAL_MODE_EXCEPT_H1; config->mimemap = h2o_mimemap_create(); h2o_socketpool_init_global(&config->proxy.global_socketpool, SIZE_MAX); h2o_configurator__init_core(config); }
h2o_memcached_context_t *h2o_memcached_create_context(const char *host, uint16_t port, size_t num_threads, const char *prefix) { h2o_memcached_context_t *ctx = h2o_mem_alloc(sizeof(*ctx)); pthread_mutex_init(&ctx->mutex, NULL); pthread_cond_init(&ctx->cond, NULL); h2o_linklist_init_anchor(&ctx->pending); ctx->num_threads_connected = 0; ctx->host = h2o_strdup(NULL, host, SIZE_MAX).base; ctx->port = port; ctx->prefix = h2o_strdup(NULL, prefix, SIZE_MAX); { /* start the threads */ pthread_t tid; pthread_attr_t attr; size_t i; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, 1); for (i = 0; i != num_threads; ++i) h2o_multithread_create_thread(&tid, &attr, thread_main, ctx); pthread_attr_destroy(&attr); } return ctx; }
h2o_multithread_queue_t *h2o_multithread_create_queue(h2o_loop_t *loop) { h2o_multithread_queue_t *queue = h2o_mem_alloc(sizeof(*queue)); *queue = (h2o_multithread_queue_t){}; #if H2O_USE_LIBUV uv_async_init(loop, &queue->async, (void *)queue_cb); #else init_async(queue, loop); #endif pthread_mutex_init(&queue->mutex, NULL); h2o_linklist_init_anchor(&queue->receivers.active); h2o_linklist_init_anchor(&queue->receivers.inactive); return queue; }
h2o_cache_t *h2o_cache_create(int flags, size_t capacity, uint64_t duration, void (*destroy_cb)(h2o_iovec_t value)) { h2o_cache_t *cache = h2o_mem_alloc(sizeof(*cache)); cache->flags = flags; cache->table = kh_init(cache); cache->size = 0; cache->capacity = capacity; h2o_linklist_init_anchor(&cache->lru); h2o_linklist_init_anchor(&cache->age); cache->duration = duration; cache->destroy_cb = destroy_cb; if ((cache->flags & H2O_CACHE_FLAG_MULTITHREADED) != 0) pthread_mutex_init(&cache->mutex, NULL); return cache; }
void h2o_timeout_init(h2o_loop_t *loop, h2o_timeout_t *timeout, uint64_t millis) { memset(timeout, 0, sizeof(*timeout)); timeout->timeout = millis; h2o_linklist_init_anchor(&timeout->_entries); h2o_timeout__do_init(loop, timeout); }
void h2o_multithread_register_receiver(h2o_multithread_queue_t *queue, h2o_multithread_receiver_t *receiver, h2o_multithread_receiver_cb cb) { receiver->queue = queue; receiver->_link = (h2o_linklist_t){}; h2o_linklist_init_anchor(&receiver->_messages); receiver->cb = cb; h2o_linklist_insert(&queue->receivers.inactive, &receiver->_link); }
h2o_filecache_t *h2o_filecache_create(size_t capacity) { h2o_filecache_t *cache = h2o_mem_alloc(sizeof(*cache)); cache->hash = kh_init(opencache_set); h2o_linklist_init_anchor(&cache->lru); cache->capacity = capacity; return cache; }
void h2o_context_init(h2o_context_t *ctx, h2o_loop_t *loop, h2o_globalconf_t *config) { size_t i, j; assert(config->hosts[0] != NULL); memset(ctx, 0, sizeof(*ctx)); ctx->loop = loop; ctx->globalconf = config; h2o_timeout_init(ctx->loop, &ctx->zero_timeout, 0); h2o_timeout_init(ctx->loop, &ctx->one_sec_timeout, 1000); h2o_timeout_init(ctx->loop, &ctx->hundred_ms_timeout, 100); ctx->queue = h2o_multithread_create_queue(loop); h2o_multithread_register_receiver(ctx->queue, &ctx->receivers.hostinfo_getaddr, h2o_hostinfo_getaddr_receiver); ctx->filecache = h2o_filecache_create(config->filecache.capacity); h2o_timeout_init(ctx->loop, &ctx->handshake_timeout, config->handshake_timeout); h2o_timeout_init(ctx->loop, &ctx->http1.req_timeout, config->http1.req_timeout); h2o_linklist_init_anchor(&ctx->http1._conns); h2o_timeout_init(ctx->loop, &ctx->http2.idle_timeout, config->http2.idle_timeout); h2o_linklist_init_anchor(&ctx->http2._conns); ctx->proxy.client_ctx.loop = loop; h2o_timeout_init(ctx->loop, &ctx->proxy.io_timeout, config->proxy.io_timeout); ctx->proxy.client_ctx.getaddr_receiver = &ctx->receivers.hostinfo_getaddr; ctx->proxy.client_ctx.io_timeout = &ctx->proxy.io_timeout; ctx->proxy.client_ctx.ssl_ctx = config->proxy.ssl_ctx; ctx->_module_configs = h2o_mem_alloc(sizeof(*ctx->_module_configs) * config->_num_config_slots); memset(ctx->_module_configs, 0, sizeof(*ctx->_module_configs) * config->_num_config_slots); static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&mutex); for (i = 0; config->hosts[i] != NULL; ++i) { h2o_hostconf_t *hostconf = config->hosts[i]; for (j = 0; j != hostconf->paths.size; ++j) { h2o_pathconf_t *pathconf = hostconf->paths.entries + j; h2o_context_init_pathconf_context(ctx, pathconf); } h2o_context_init_pathconf_context(ctx, &hostconf->fallback_path); } pthread_mutex_unlock(&mutex); }
static void common_init(h2o_socketpool_t *pool, h2o_socketpool_type_t type, size_t capacity) { memset(pool, 0, sizeof(*pool)); pool->type = type; pool->capacity = capacity; pool->timeout = UINT64_MAX; pthread_mutex_init(&pool->_shared.mutex, NULL); h2o_linklist_init_anchor(&pool->_shared.sockets); }
static void common_init(h2o_socketpool_t *pool, h2o_socketpool_type_t type, h2o_iovec_t host, int is_ssl, size_t capacity) { memset(pool, 0, sizeof(*pool)); pool->type = type; pool->peer.host = h2o_strdup(NULL, host.base, host.len); pool->is_ssl = is_ssl; pool->capacity = capacity; pool->timeout = UINT64_MAX; pthread_mutex_init(&pool->_shared.mutex, NULL); h2o_linklist_init_anchor(&pool->_shared.sockets); }
static void common_init(h2o_socketpool_t *pool, h2o_socketpool_target_t **targets, size_t num_targets, size_t capacity, h2o_balancer_t *balancer) { memset(pool, 0, sizeof(*pool)); pool->capacity = capacity; pool->timeout = 2000; pthread_mutex_init(&pool->_shared.mutex, NULL); h2o_linklist_init_anchor(&pool->_shared.sockets); h2o_vector_reserve(NULL, &pool->targets, num_targets); for (; pool->targets.size < num_targets; ++pool->targets.size) pool->targets.entries[pool->targets.size] = targets[pool->targets.size]; pool->balancer = balancer; }
void h2o_socketpool_init(h2o_socketpool_t *pool, const char *host, uint16_t port, size_t capacity) { memset(pool, 0, sizeof(*pool)); if (inet_pton(AF_INET, host, &pool->peer.sin.sin_addr) == 1) { pool->peer.sin.sin_family = AF_INET; pool->peer.sin.sin_port = htons(port); } else { pool->peer.named.host = h2o_strdup(NULL, host, SIZE_MAX); sprintf(pool->peer.named.port, "%u", (unsigned)port); pool->peer.is_named = 1; } pool->capacity = capacity; pool->timeout = UINT64_MAX; pthread_mutex_init(&pool->_shared.mutex, NULL); h2o_linklist_init_anchor(&pool->_shared.sockets); }
void h2o_socketpool_init(h2o_socketpool_t *pool, h2o_iovec_t host, uint16_t port, size_t capacity) { memset(pool, 0, sizeof(*pool)); if (h2o_hostinfo_aton(host, &pool->peer.sin.sin_addr) == 0) { pool->peer.sin.sin_family = AF_INET; pool->peer.sin.sin_port = htons(port); } else { pool->peer.named.host = h2o_strdup(NULL, host.base, host.len); pool->peer.named.port.base = h2o_mem_alloc(sizeof("65535")); pool->peer.named.port.len = sprintf(pool->peer.named.port.base, "%u", (unsigned)port); pool->peer.is_named = 1; } pool->capacity = capacity; pool->timeout = UINT64_MAX; pthread_mutex_init(&pool->_shared.mutex, NULL); h2o_linklist_init_anchor(&pool->_shared.sockets); }
void h2o_config_init(h2o_globalconf_t *config) { memset(config, 0, sizeof(*config)); config->hosts = h2o_mem_alloc(sizeof(config->hosts[0])); config->hosts[0] = NULL; h2o_linklist_init_anchor(&config->configurators); config->server_name = h2o_iovec_init(H2O_STRLIT("h2o/" H2O_VERSION)); config->max_request_entity_size = H2O_DEFAULT_MAX_REQUEST_ENTITY_SIZE; config->max_delegations = H2O_DEFAULT_MAX_DELEGATIONS; config->handshake_timeout = H2O_DEFAULT_HANDSHAKE_TIMEOUT; config->http1.req_timeout = H2O_DEFAULT_HTTP1_REQ_TIMEOUT; config->http1.upgrade_to_http2 = H2O_DEFAULT_HTTP1_UPGRADE_TO_HTTP2; config->http1.callbacks = H2O_HTTP1_CALLBACKS; config->http2.idle_timeout = H2O_DEFAULT_HTTP2_IDLE_TIMEOUT; config->proxy.io_timeout = H2O_DEFAULT_PROXY_IO_TIMEOUT; config->http2.max_concurrent_requests_per_connection = H2O_HTTP2_SETTINGS_HOST.max_concurrent_streams; config->http2.max_streams_for_priority = 16; config->http2.callbacks = H2O_HTTP2_CALLBACKS; config->mimemap = h2o_mimemap_create(); h2o_configurator__init_core(config); }
static void queue_cb(h2o_multithread_queue_t *queue) { pthread_mutex_lock(&queue->mutex); while (!h2o_linklist_is_empty(&queue->receivers.active)) { h2o_multithread_receiver_t *receiver = H2O_STRUCT_FROM_MEMBER(h2o_multithread_receiver_t, _link, queue->receivers.active.next); /* detach all the messages from the receiver */ h2o_linklist_t messages; h2o_linklist_init_anchor(&messages); h2o_linklist_insert_list(&messages, &receiver->_messages); /* relink the receiver to the inactive list */ h2o_linklist_unlink(&receiver->_link); h2o_linklist_insert(&queue->receivers.inactive, &receiver->_link); /* dispatch the messages */ pthread_mutex_unlock(&queue->mutex); receiver->cb(receiver, &messages); assert(h2o_linklist_is_empty(&messages)); pthread_mutex_lock(&queue->mutex); } pthread_mutex_unlock(&queue->mutex); }
static void init_node(h2o_http2_scheduler_node_t *node, h2o_http2_scheduler_node_t *parent) { *node = (h2o_http2_scheduler_node_t){parent}; h2o_linklist_init_anchor(&node->_all_refs); }