src/server/daemon/config.c

changeset 61
c858850f3d3a
parent 60
feb2f1e115c6
child 62
c47e081b6c0f
--- 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;
 }
 

mercurial