diff -r feb2f1e115c6 -r c858850f3d3a src/server/daemon/config.c --- a/src/server/daemon/config.c Mon May 06 14:54:40 2013 +0200 +++ b/src/server/daemon/config.c Thu May 09 13:19:51 2013 +0200 @@ -104,7 +104,7 @@ /* execute init directive */ int ret = d->func->func(d->param, NULL, NULL); - if(ret != REQ_PROCEED || ret != REQ_NOACTION) { + if(ret != REQ_PROCEED && ret != REQ_NOACTION) { log_ereport( LOG_FAILURE, "Error running Init function %s", @@ -251,6 +251,7 @@ uint32_t ref = ws_atomic_dec32(&cfg->ref); if(ref == 0) { // TODO: free configuration + printf("free ServerConfiguration %d\n", cfg); } } @@ -280,15 +281,21 @@ ConfigFile *f = cfgmgr_get_file(file); if(f == NULL) { f = malloc(sizeof(ConfigFile)); + f->data = NULL; f->file = sstrdup(file); f->reload = mime_conf_reload; // load the file content - f->reload(f, cfg); + //f->reload(f, cfg); + if(cfgmgr_reload_file(f, cfg, NULL)) { + free(f->file.ptr); + free(f); + return -1; + } cfgmgr_attach_file(f); } - cfg->mimetypes = f->data; // TODO: ref + cfg->mimetypes = f->data; return 0; } @@ -531,13 +538,19 @@ ConfigFile *f = cfgmgr_get_file(file); if(f == NULL) { f = malloc(sizeof(ConfigFile)); + f->data = NULL; f->file = sstrdup(file); f->reload = object_conf_reload; - f->reload(f, cfg); + //f->reload(f, cfg); + if(cfgmgr_reload_file(f, cfg, NULL)) { + free(f->file.ptr); + free(f); + return -1; + } cfgmgr_attach_file(f); } - vs->objectfile = sstrdup(file); // TODO: pool - vs->objects = (HTTPObjectConfig*)f->data; // TODO: ref + vs->objectfile = sstrdup(file); + vs->objects = (HTTPObjectConfig*)f->data; // load acl config file file.length = base.length + aclfile.length + 1; @@ -548,11 +561,18 @@ ConfigFile *aclf = cfgmgr_get_file(file); if(aclf == NULL) { aclf = malloc(sizeof(ConfigFile)); + aclf->data = NULL; aclf->file = sstrdup(file); aclf->reload = acl_conf_reload; - aclf->reload(aclf, cfg); + //aclf->reload(aclf, cfg); + if(cfgmgr_reload_file(aclf, cfg, NULL)) { + free(aclf->file.ptr); + free(aclf); + return -1; + } cfgmgr_attach_file(aclf); } + vs->acls = aclf->data; // set the access log for the virtual server // TODO: don't use always the default @@ -565,14 +585,30 @@ int object_conf_reload(ConfigFile *file, ServerConfiguration *cfg) { + HTTPObjectConfig *old_conf = file->data; file->data = load_obj_conf(file->file.ptr); - struct stat s; - if(stat(file->file.ptr, &s) != 0) { - perror("object_conf_reload: stat"); - return -1; + if(old_conf) { + object_conf_unref(old_conf); + } + if(file->data) { + return 0; + } else { + return 1; } - file->last_modified = s.st_mtim.tv_sec; - return 0; +} + +void object_conf_ref(HTTPObjectConfig *conf) { + if(conf) { + ws_atomic_inc32(&conf->ref); + } +} + +void object_conf_unref(HTTPObjectConfig *conf) { + uint32_t ref = ws_atomic_dec32(&conf->ref); + if(ref == 0) { + printf("free HTTPObjectConfig %d\n", conf); + pool_destroy(conf->pool); + } } HTTPObjectConfig* load_obj_conf(char *file) { @@ -586,14 +622,15 @@ } /* create object config */ - HTTPObjectConfig *conf = calloc(sizeof(HTTPObjectConfig), 1); - conf->pool = pool_create(); + pool_handle_t *pool = pool_create(); + HTTPObjectConfig *conf = pool_calloc(pool, sizeof(HTTPObjectConfig), 1); + conf->pool = pool; /* convert ObjectConfig to HTTPObjectConfig */ /* add objects */ conf->nobj = ucx_dlist_size(cfg->objects); - conf->objects = calloc(1, sizeof(httpd_object*)); + conf->objects = pool_calloc(pool, 1, sizeof(httpd_object*)); UcxDlist *objlist = cfg->objects; int i = 0; @@ -604,14 +641,14 @@ char *name = NULL; char *ppath = NULL; if(cob->name.length > 0) { - name = sstrdup(cob->name).ptr; + name = sstrdup_pool(pool, cob->name).ptr; } if(cob->ppath.length > 0) { - ppath = sstrdup(cob->ppath).ptr; + ppath = sstrdup_pool(pool, cob->ppath).ptr; } /* create and add object */ - httpd_object *obj = object_new(name); + httpd_object *obj = object_new(pool, name); obj->path = NULL; conf->objects[i] = obj; // TODO: beyond array bounds write @@ -622,9 +659,9 @@ while(dirs != NULL) { ConfigDirective *cfgdir = dirs->data; - directive *d = malloc(sizeof(directive)); + directive *d = pool_malloc(pool, sizeof(directive)); d->cond = NULL; - d->param = pblock_create_pool(conf->pool, 8); + d->param = pblock_create_pool(pool, 8); /* add params */ UcxList *param = cfg_param_list(cfgdir->value, mp); @@ -662,8 +699,12 @@ int mime_conf_reload(ConfigFile *file, ServerConfiguration *cfg) { MimeConfig *mimecfg = load_mime_config(file->file.ptr); + MimeMap *old_conf = file->data; - UcxMap *mimemap = ucx_map_new((mimecfg->ntypes * 3) / 2); + MimeMap *mimemap = malloc(sizeof(MimeMap)); + mimemap->ref = 1; + UcxMap *map = ucx_map_new((mimecfg->ntypes * 3) / 2); + mimemap->map = map; // add ext type pairs UCX_FOREACH(UcxList*, mimecfg->directives, md) { @@ -672,14 +713,39 @@ UCX_FOREACH(UcxList*, d->exts, xl) { sstr_t ext = sstr(xl->data); sstr_t value = sstrdup(d->type); - ucx_map_sstr_put(mimemap, ext, value.ptr); + ucx_map_sstr_put(map, ext, value.ptr); } } file->data = mimemap; + + if(old_conf) { + mime_conf_unref(old_conf); + } + return 0; } +void mime_conf_ref(MimeMap *conf) { + if(conf) { + ws_atomic_inc32(&conf->ref); + } +} + +void mime_conf_unref(MimeMap *conf) { + uint32_t ref = ws_atomic_dec32(&conf->ref); + if(ref == 0) { + printf("free MimeConfig %d\n", conf); + UcxMapIterator i = ucx_map_iterator(conf->map); + char *str; + UCX_MAP_FOREACH(str, i) { + free(str); + } + ucx_map_free(conf->map); + free(conf); + } +} + int acl_conf_reload(ConfigFile *file, ServerConfiguration *cfg) { ACLFile *aclfile = load_acl_file(file->file.ptr); @@ -691,14 +757,12 @@ } free_acl_file(aclfile); - cfg->acls = acldata; + ACLData *old_data = file->data; + file->data = acldata; + if(old_data) { + acl_data_unref(old_data); + } - struct stat s; - if(stat(file->file.ptr, &s) != 0) { - perror("object_conf_reload: stat"); - return -1; - } - file->last_modified = s.st_mtim.tv_sec; return 0; }