From 032dd86db2315c403fcdeebb00f9330ea8c25ef9 Mon Sep 17 00:00:00 2001 From: Dmitry Simonenko Date: Thu, 13 Jul 2017 15:58:32 +0300 Subject: [PATCH] odissey: add scheme reference counting and cleanup --- odissey.conf | 12 ++---- sources/config.c | 15 ++++---- sources/instance.c | 16 +++----- sources/scheme.c | 93 +++++++++++++++++++++++++++++++++++++++++----- sources/scheme.h | 14 +++++-- 5 files changed, 111 insertions(+), 39 deletions(-) diff --git a/odissey.conf b/odissey.conf index 26888ba4..4a2c7519 100644 --- a/odissey.conf +++ b/odissey.conf @@ -16,8 +16,7 @@ pipelining 16384 client_max 100 workers 3 -listen -{ +listen { host "*" port 6432 nodelay yes @@ -30,13 +29,11 @@ listen # tls_protocols "" } -storage "local" -{ +storage "local" { type "local" } -storage "pg_server" -{ +storage "pg_server" { type "remote" host "127.0.0.1" port 5432 @@ -47,8 +44,7 @@ storage "pg_server" # tls_protocols "" } -database "console" -{ +database "console" { user default { authentication "none" pool "session" diff --git a/sources/config.c b/sources/config.c index a64f28e0..d06acfc7 100644 --- a/sources/config.c +++ b/sources/config.c @@ -83,11 +83,12 @@ enum typedef struct { - od_parser_t parser; - od_log_t *log; + od_parser_t parser; od_scheme_t *scheme; - char *data; - int data_size; + od_log_t *log; + char *config_file; + char *data; + int data_size; } od_config_t; #define od_keyword(name, token) { token, name, sizeof(name) - 1 } @@ -148,6 +149,7 @@ static od_keyword_t od_config_keywords[] = static int od_config_open(od_config_t *config, char *config_file) { + config->config_file = config_file; /* read file */ struct stat st; int rc = lstat(config_file, &st); @@ -176,7 +178,6 @@ od_config_open(od_config_t *config, char *config_file) config_file); return -1; } - config->scheme->config_file = config_file; config->data = config_buf; config->data_size = st.st_size; od_parser_init(&config->parser, config->data, config->data_size); @@ -200,8 +201,8 @@ od_config_error(od_config_t *config, od_token_t *token, char *fmt, ...) int line = config->parser.line; if (token) line = token->line; - od_error(config->log, "config", "%s:%d %s", - config->scheme->config_file, line, msg); + od_error(config->log, "config", "%s:%d %s", config->config_file, + line, msg); } static bool diff --git a/sources/instance.c b/sources/instance.c index ab49ae87..c7150377 100644 --- a/sources/instance.c +++ b/sources/instance.c @@ -86,15 +86,12 @@ int od_instance_main(od_instance_t *instance, int argc, char **argv) od_usage(instance, argv[0]); return -1; } - char *config_file; - if (argc == 2) { - if (strcmp(argv[1], "-h") == 0 || - strcmp(argv[1], "--help") == 0) { - od_usage(instance, argv[0]); - return 0; - } - config_file = argv[1]; + if (strcmp(argv[1], "-h") == 0 || + strcmp(argv[1], "--help") == 0) { + od_usage(instance, argv[0]); + return 0; } + char *config_file = argv[1]; /* read config file */ int rc; @@ -140,8 +137,7 @@ int od_instance_main(od_instance_t *instance, int argc, char **argv) return -1; /* print configuration */ - od_log(&instance->log, "using configuration file '%s'", - instance->scheme.config_file); + od_log(&instance->log, "using configuration file '%s'", config_file); od_log(&instance->log, ""); if (instance->scheme.log_config) od_scheme_print(&instance->scheme, &instance->log); diff --git a/sources/scheme.c b/sources/scheme.c index db949225..ab97979c 100644 --- a/sources/scheme.c +++ b/sources/scheme.c @@ -23,7 +23,6 @@ void od_scheme_init(od_scheme_t *scheme) { - scheme->config_file = NULL; scheme->daemonize = 0; scheme->log_debug = 0; scheme->log_config = 0; @@ -61,19 +60,33 @@ void od_scheme_free(od_scheme_t *scheme) od_list_foreach_safe(&scheme->dbs, i, n) { od_schemedb_t *db; db = od_container_of(i, od_schemedb_t, link); - od_list_t *p, *q; - od_list_foreach_safe(&db->users, p, q) { - od_schemeuser_t *user; - user = od_container_of(p, od_schemeuser_t, link); - free(user); - } - free(db); + od_schemedb_unref(db); } od_list_foreach_safe(&scheme->storages, i, n) { od_schemestorage_t *storage; storage = od_container_of(i, od_schemestorage_t, link); od_schemestorage_unref(storage); } + if (scheme->log_file) + free(scheme->log_file); + if (scheme->pid_file) + free(scheme->pid_file); + if (scheme->syslog_ident) + free(scheme->syslog_ident); + if (scheme->syslog_facility) + free(scheme->syslog_facility); + if (scheme->host) + free(scheme->host); + if (scheme->tls) + free(scheme->tls); + if (scheme->tls_ca_file) + free(scheme->tls_ca_file); + if (scheme->tls_key_file) + free(scheme->tls_key_file); + if (scheme->tls_cert_file) + free(scheme->tls_cert_file); + if (scheme->tls_protocols) + free(scheme->tls_protocols); } od_schemestorage_t* @@ -162,6 +175,32 @@ od_schemedb_match(od_scheme_t *scheme, char *name) return NULL; } +void od_schemedb_ref(od_schemedb_t *db) +{ + db->refs++; +} + +static void +od_schemeuser_free(od_schemeuser_t*); + +void od_schemedb_unref(od_schemedb_t *db) +{ + if (db->refs > 0) + --db->refs; + if (db->refs > 0) + return; + od_list_t *i, *n; + od_list_foreach_safe(&db->users, i, n) { + od_schemeuser_t *user; + user = od_container_of(i, od_schemeuser_t, link); + od_schemeuser_free(user); + } + if (db->name) + free(db->name); + od_list_unlink(&db->link); + free(db); +} + od_schemeuser_t* od_schemeuser_add(od_schemedb_t *db) { @@ -174,7 +213,6 @@ od_schemeuser_add(od_schemedb_t *db) user->pool_cancel = 1; user->pool_discard = 1; user->pool_rollback = 1; - user->pool = OD_PSESSION; od_list_init(&user->link); od_list_append(&db->users, &user->link); return user; @@ -195,6 +233,40 @@ od_schemeuser_match(od_schemedb_t *db, char *name) return NULL; } +void od_schemeuser_ref(od_schemeuser_t *user) +{ + od_schemedb_ref(user->db); +} + +void od_schemeuser_unref(od_schemeuser_t *user) +{ + od_schemedb_unref(user->db); +} + +static void +od_schemeuser_free(od_schemeuser_t *user) +{ + if (user->user) + free(user->user); + if (user->user_password) + free(user->user_password); + if (user->auth) + free(user->auth); + if (user->storage) + od_schemestorage_unref(user->storage); + if (user->storage_name) + free(user->storage_name); + if (user->storage_db) + free(user->storage_db); + if (user->storage_user) + free(user->storage_user); + if (user->storage_password) + free(user->storage_password); + if (user->pool_sz) + free(user->pool_sz); + free(user); +} + int od_scheme_validate(od_scheme_t *scheme, od_log_t *log) { /* workers */ @@ -316,13 +388,14 @@ int od_scheme_validate(od_scheme_t *scheme, od_log_t *log) db->name, user->user); return -1; } - /* match storage */ + /* match storage and make a reference */ user->storage = od_schemestorage_match(scheme, user->storage_name); if (user->storage == NULL) { od_error(log, "config", "db '%s' user '%s': no route storage '%s' found", db->name, user->user); return -1; } + od_schemestorage_ref(user->storage); /* pooling mode */ if (! user->pool_sz) { diff --git a/sources/scheme.h b/sources/scheme.h index 88c68270..30c95f00 100644 --- a/sources/scheme.h +++ b/sources/scheme.h @@ -66,6 +66,7 @@ struct od_schemedb od_list_t users; od_schemeuser_t *user_default; int is_default; + int refs; od_list_t link; }; @@ -106,7 +107,6 @@ struct od_schemeuser struct od_scheme { - char *config_file; /* main */ int daemonize; int log_debug; @@ -150,22 +150,28 @@ void od_scheme_print(od_scheme_t*, od_log_t*); od_schemestorage_t* od_schemestorage_add(od_scheme_t*); -void od_schemestorage_ref(od_schemestorage_t*); -void od_schemestorage_unref(od_schemestorage_t*); - od_schemestorage_t* od_schemestorage_match(od_scheme_t*, char*); +void od_schemestorage_ref(od_schemestorage_t*); +void od_schemestorage_unref(od_schemestorage_t*); + od_schemedb_t* od_schemedb_add(od_scheme_t*); od_schemedb_t* od_schemedb_match(od_scheme_t*, char*); +void od_schemedb_ref(od_schemedb_t*); +void od_schemedb_unref(od_schemedb_t*); + od_schemeuser_t* od_schemeuser_add(od_schemedb_t*); od_schemeuser_t* od_schemeuser_match(od_schemedb_t*, char*); +void od_schemeuser_ref(od_schemeuser_t*); +void od_schemeuser_unref(od_schemeuser_t*); + #endif /* OD_SCHEME_H */