odissey: add scheme reference counting and cleanup

This commit is contained in:
Dmitry Simonenko 2017-07-13 15:58:32 +03:00
parent b5d5a9a3e7
commit 032dd86db2
5 changed files with 111 additions and 39 deletions

View File

@ -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"

View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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 */