static h2o_hostconf_t *create_hostconf(h2o_globalconf_t *globalconf) { h2o_hostconf_t *hostconf = h2o_mem_alloc(sizeof(*hostconf)); *hostconf = (h2o_hostconf_t){globalconf}; h2o_config_init_pathconf(&hostconf->fallback_path, globalconf, NULL, globalconf->mimemap); hostconf->mimemap = globalconf->mimemap; h2o_mem_addref_shared(hostconf->mimemap); return hostconf; }
static int on_config_enter(h2o_configurator_t *_self, h2o_configurator_context_t *ctx, yoml_t *node) { struct st_h2o_file_configurator_t *self = (void *)_self; ++self->vars; self->vars[0].index_files = dup_strlist(self->vars[-1].index_files); self->vars[0].mimemap = self->vars[-1].mimemap; self->vars[0].flags = self->vars[-1].flags; h2o_mem_addref_shared(self->vars[0].mimemap); return 0; }
void h2o_config_init_pathconf(h2o_pathconf_t *pathconf, h2o_globalconf_t *globalconf, const char *path, h2o_mimemap_t *mimemap) { memset(pathconf, 0, sizeof(*pathconf)); pathconf->global = globalconf; h2o_chunked_register(pathconf); if (path != NULL) pathconf->path = h2o_strdup_slashed(NULL, path, SIZE_MAX); h2o_mem_addref_shared(mimemap); pathconf->mimemap = mimemap; }
static h2o_hostconf_t *create_hostconf(h2o_globalconf_t *globalconf) { h2o_hostconf_t *hostconf = h2o_mem_alloc(sizeof(*hostconf)); *hostconf = (h2o_hostconf_t){globalconf}; hostconf->http2.push_preload = 1; /* enabled by default */ h2o_config_init_pathconf(&hostconf->fallback_path, globalconf, NULL, globalconf->mimemap); hostconf->mimemap = globalconf->mimemap; h2o_mem_addref_shared(hostconf->mimemap); return hostconf; }
void h2o_config_init_pathconf(h2o_pathconf_t *pathconf, h2o_globalconf_t *globalconf, const char *path, h2o_mimemap_t *mimemap) { memset(pathconf, 0, sizeof(*pathconf)); pathconf->global = globalconf; if (path != NULL) pathconf->path = h2o_strdup(NULL, path, SIZE_MAX); h2o_mem_addref_shared(mimemap); pathconf->mimemap = mimemap; pathconf->error_log.emit_request_errors = 1; }
h2o_logger_t *h2o_access_log_register(h2o_pathconf_t *pathconf, h2o_access_log_filehandle_t *fh) { struct st_h2o_access_logger_t *self = (void *)h2o_create_logger(pathconf, sizeof(*self)); self->super.dispose = dispose; self->super.log_access = log_access; self->fh = fh; h2o_mem_addref_shared(fh); return &self->super; }
h2o_envconf_t *h2o_config_create_envconf(h2o_envconf_t *parent) { h2o_envconf_t *envconf = h2o_mem_alloc_shared(NULL, sizeof(*envconf), on_dispose_envconf); *envconf = (h2o_envconf_t){NULL}; if (parent != NULL) { envconf->parent = parent; h2o_mem_addref_shared(parent); } return envconf; }
static h2o_configurator_context_t *create_context(h2o_configurator_context_t *parent, int is_custom_handler) { h2o_configurator_context_t *ctx = h2o_mem_alloc(sizeof(*ctx)); if (parent == NULL) { *ctx = (h2o_configurator_context_t){}; return ctx; } *ctx = *parent; if (ctx->env != NULL) h2o_mem_addref_shared(ctx->env); ctx->parent = parent; return ctx; }
h2o_handler_t *h2o_file_register_file(h2o_pathconf_t *pathconf, const char *real_path, h2o_mimemap_type_t *mime_type, int flags) { struct st_h2o_specific_file_handler_t *self = (void *)h2o_create_handler(pathconf, sizeof(*self)); self->super.on_context_init = specific_handler_on_context_init; self->super.on_context_dispose = specific_handler_on_context_dispose; self->super.dispose = specific_handler_on_dispose; self->super.on_req = specific_handler_on_req; self->real_path = h2o_strdup(NULL, real_path, SIZE_MAX); h2o_mem_addref_shared(mime_type); self->mime_type = mime_type; self->flags = flags; return &self->super; }
static int on_config_enter(h2o_configurator_t *_self, h2o_configurator_context_t *ctx, const char *file, yoml_t *node) { struct st_h2o_access_log_configurator_t *self = (void*)_self; size_t i; /* push the stack pointer */ ++self->handles; /* link the handles */ memset(self->handles, 0, sizeof(*self->handles)); h2o_vector_reserve(NULL, (void*)self->handles, sizeof(self->handles->entries[0]), self->handles[-1].size + 1); for (i = 0; i != self->handles[-1].size; ++i) { h2o_access_log_filehandle_t *fh = self->handles[-1].entries[i]; self->handles[0].entries[self->handles[0].size++] = fh; h2o_mem_addref_shared(fh); } return 0; }
h2o_file_handler_t *h2o_file_register(h2o_pathconf_t *pathconf, const char *real_path, const char **index_files, h2o_mimemap_t *mimemap, int flags) { h2o_file_handler_t *self; size_t i; if (index_files == NULL) index_files = default_index_files; /* allocate memory */ for (i = 0; index_files[i] != NULL; ++i) ; self = (void *)h2o_create_handler(pathconf, offsetof(h2o_file_handler_t, index_files[0]) + sizeof(self->index_files[0]) * (i + 1)); /* setup callbacks */ self->super.on_context_init = on_context_init; self->super.on_context_dispose = on_context_dispose; self->super.dispose = on_dispose; self->super.on_req = on_req; /* setup attributes */ self->conf_path = h2o_strdup_slashed(NULL, pathconf->path.base, pathconf->path.len); self->real_path = h2o_strdup_slashed(NULL, real_path, SIZE_MAX); if (mimemap != NULL) { h2o_mem_addref_shared(mimemap); self->mimemap = mimemap; } else { self->mimemap = h2o_mimemap_create(); } self->flags = flags; for (i = 0; index_files[i] != NULL; ++i) { self->index_files[i] = h2o_strdup(NULL, index_files[i], SIZE_MAX); if (self->max_index_file_len < self->index_files[i].len) self->max_index_file_len = self->index_files[i].len; } return self; }
static void do_updates(multiple_query_ctx_t *query_ctx) { thread_context_t * const ctx = H2O_STRUCT_FROM_MEMBER(thread_context_t, event_loop.h2o_ctx, query_ctx->req->conn->ctx); char *iter = (char *) (query_ctx->query_param + 1); size_t sz = MAX_UPDATE_QUERY_LEN(query_ctx->num_result); // Sort the results to avoid database deadlock. qsort(query_ctx->res, query_ctx->num_result, sizeof(*query_ctx->res), compare_items); query_ctx->query_param->param.command = iter; query_ctx->query_param->param.nParams = 0; query_ctx->query_param->param.on_result = on_update_result; query_ctx->query_param->param.paramFormats = NULL; query_ctx->query_param->param.paramLengths = NULL; query_ctx->query_param->param.paramValues = NULL; query_ctx->query_param->param.flags = 0; query_ctx->res->random_number = get_random_number(MAX_ID, &ctx->random_seed) + 1; int c = snprintf(iter, sz, UPDATE_QUERY_BEGIN, query_ctx->res->id, query_ctx->res->random_number); if ((size_t) c >= sz) goto error; iter += c; sz -= c; for (size_t i = 1; i < query_ctx->num_result; i++) { query_ctx->res[i].random_number = get_random_number(MAX_ID, &ctx->random_seed) + 1; c = snprintf(iter, sz, UPDATE_QUERY_ELEM, query_ctx->res[i].id, query_ctx->res[i].random_number); if ((size_t) c >= sz) goto error; iter += c; sz -= c; } c = snprintf(iter, sz, UPDATE_QUERY_END); if ((size_t) c >= sz) goto error; if (execute_query(ctx, &query_ctx->query_param->param)) send_service_unavailable_error(DB_REQ_ERROR, query_ctx->req); else { query_ctx->num_query_in_progress++; h2o_mem_addref_shared(query_ctx); } return; error: LIBRARY_ERROR("snprintf", "Truncated output."); send_error(INTERNAL_SERVER_ERROR, REQ_ERROR, query_ctx->req); }
static int do_multiple_queries(bool do_update, bool use_cache, h2o_req_t *req) { thread_context_t * const ctx = H2O_STRUCT_FROM_MEMBER(thread_context_t, event_loop.h2o_ctx, req->conn->ctx); const size_t num_query = get_query_number(req); // MAX_QUERIES is a relatively small number, so assume no overflow in the following // arithmetic operations. assert(num_query <= MAX_QUERIES); size_t base_size = offsetof(multiple_query_ctx_t, res) + num_query * sizeof(query_result_t); base_size = ((base_size + _Alignof(query_param_t) - 1) / _Alignof(query_param_t)); base_size = base_size * _Alignof(query_param_t); const size_t num_query_in_progress = MIN(num_query, ctx->config->max_db_conn_num); size_t sz = base_size + num_query_in_progress * sizeof(query_param_t); if (do_update) { const size_t reuse_size = (num_query_in_progress - 1) * sizeof(query_param_t); const size_t update_query_len = MAX_UPDATE_QUERY_LEN(num_query); if (update_query_len > reuse_size) sz += update_query_len - reuse_size; } multiple_query_ctx_t * const query_ctx = h2o_mem_alloc_shared(&req->pool, sz, cleanup_multiple_query); if (query_ctx) { memset(query_ctx, 0, sz); query_ctx->num_query = num_query; query_ctx->req = req; query_ctx->do_update = do_update; query_ctx->use_cache = use_cache; query_ctx->query_param = (query_param_t *) ((char *) query_ctx + base_size); initialize_ids(num_query, query_ctx->res, &ctx->random_seed); if (use_cache) { fetch_from_cache(h2o_now(ctx->event_loop.h2o_ctx.loop), ctx->global_data->world_cache, query_ctx); if (query_ctx->num_result == query_ctx->num_query) { complete_multiple_query(query_ctx); return 0; } } query_ctx->num_query_in_progress = MIN(num_query_in_progress, query_ctx->num_query - query_ctx->num_result); for (size_t i = 0; i < query_ctx->num_query_in_progress; i++) { query_ctx->query_param[i].ctx = query_ctx; // We need a copy of id because the original may be overwritten // by a completed query. query_ctx->query_param[i].id = htonl(query_ctx->res[query_ctx->num_result + i].id); query_ctx->query_param[i].id_format = 1; query_ctx->query_param[i].id_len = sizeof(query_ctx->query_param[i].id); query_ctx->query_param[i].id_pointer = (const char *) &query_ctx->query_param[i].id; query_ctx->query_param[i].param.command = WORLD_TABLE_NAME; query_ctx->query_param[i].param.nParams = 1; query_ctx->query_param[i].param.on_error = on_multiple_query_error; query_ctx->query_param[i].param.on_result = on_multiple_query_result; query_ctx->query_param[i].param.on_timeout = on_multiple_query_timeout; query_ctx->query_param[i].param.paramFormats = &query_ctx->query_param[i].id_format; query_ctx->query_param[i].param.paramLengths = &query_ctx->query_param[i].id_len; query_ctx->query_param[i].param.paramValues = &query_ctx->query_param[i].id_pointer; query_ctx->query_param[i].param.flags = IS_PREPARED; query_ctx->query_param[i].param.resultFormat = 1; if (execute_query(ctx, &query_ctx->query_param[i].param)) { query_ctx->num_query_in_progress = i; query_ctx->error = true; send_service_unavailable_error(DB_REQ_ERROR, req); return 0; } h2o_mem_addref_shared(query_ctx); } } else send_error(INTERNAL_SERVER_ERROR, REQ_ERROR, req); return 0; }
void h2o_mem_link_shared(h2o_mem_pool_t *pool, void *p) { h2o_mem_addref_shared(p); link_shared(pool, H2O_STRUCT_FROM_MEMBER(struct st_h2o_mem_pool_shared_entry_t, bytes, p)); }