Преглед изворни кода

ncd: modules: fix modules that used global (static) variables to allocate these interpreter-wide using the new support within
NCDModule. With this done, it should become possible to have multiple instances of NCDInterpreter at the same time.

ambrop7 пре 13 година
родитељ
комит
1fc023a1e4
5 измењених фајлова са 197 додато и 58 уклоњено
  1. 47 16
      ncd/modules/depend.c
  2. 42 12
      ncd/modules/dynamic_depend.c
  3. 44 13
      ncd/modules/multidepend.c
  4. 38 12
      ncd/modules/net_dns.c
  5. 26 5
      ncd/modules/net_iptables.c

+ 47 - 16
ncd/modules/depend.c

@@ -59,6 +59,7 @@
 
 #include <misc/offset.h>
 #include <misc/debug.h>
+#include <misc/balloc.h>
 #include <structure/LinkedList1.h>
 #include <structure/LinkedList3.h>
 #include <ncd/NCDModule.h>
@@ -66,6 +67,7 @@
 #include <generated/blog_channel_ncd_depend.h>
 
 #define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__)
+#define ModuleGlobal(i) ((i)->m->group->group_state)
 
 struct provide {
     NCDModuleInst *i;
@@ -93,12 +95,14 @@ struct depend {
     LinkedList1Node node;
 };
 
-static LinkedList1 provides;
-static LinkedList1 free_depends;
+struct global {
+    LinkedList1 provides;
+    LinkedList1 free_depends;
+};
 
-static struct provide * find_provide (const char *name, size_t name_len)
+static struct provide * find_provide (struct global *g, const char *name, size_t name_len)
 {
-    for (LinkedList1Node *n = LinkedList1_GetFirst(&provides); n; n = LinkedList1Node_Next(n)) {
+    for (LinkedList1Node *n = LinkedList1_GetFirst(&g->provides); n; n = LinkedList1Node_Next(n)) {
         struct provide *p = UPPER_OBJECT(n, struct provide, provides_node);
         ASSERT(!p->is_queued)
         
@@ -112,13 +116,14 @@ static struct provide * find_provide (const char *name, size_t name_len)
 
 static void provide_promote (struct provide *o)
 {
-    ASSERT(!find_provide(o->name, o->name_len))
+    struct global *g = ModuleGlobal(o->i);
+    ASSERT(!find_provide(g, o->name, o->name_len))
     
     // set not queued
     o->is_queued = 0;
     
     // insert to provides list
-    LinkedList1_Append(&provides, &o->provides_node);
+    LinkedList1_Append(&g->provides, &o->provides_node);
     
     // init depends list
     LinkedList1_Init(&o->depends);
@@ -127,7 +132,7 @@ static void provide_promote (struct provide *o)
     o->dying = 0;
     
     // attach free depends with this name
-    LinkedList1Node *n = LinkedList1_GetFirst(&free_depends);
+    LinkedList1Node *n = LinkedList1_GetFirst(&g->free_depends);
     while (n) {
         LinkedList1Node *next = LinkedList1Node_Next(n);
         struct depend *d = UPPER_OBJECT(n, struct depend, node);
@@ -139,7 +144,7 @@ static void provide_promote (struct provide *o)
         }
         
         // remove from free depends list
-        LinkedList1_Remove(&free_depends, &d->node);
+        LinkedList1_Remove(&g->free_depends, &d->node);
         
         // insert to provide's list
         LinkedList1_Append(&o->depends, &d->node);
@@ -156,17 +161,38 @@ static void provide_promote (struct provide *o)
 
 static int func_globalinit (struct NCDInterpModuleGroup *group, const struct NCDModuleInst_iparams *params)
 {
+    // allocate global state structure
+    struct global *g = BAlloc(sizeof(*g));
+    if (!g) {
+        BLog(BLOG_ERROR, "BAlloc failed");
+        return 0;
+    }
+    
+    // set group state pointer
+    group->group_state = g;
+    
     // init provides list
-    LinkedList1_Init(&provides);
+    LinkedList1_Init(&g->provides);
     
     // init free depends list
-    LinkedList1_Init(&free_depends);
+    LinkedList1_Init(&g->free_depends);
     
     return 1;
 }
 
+static void func_globalfree (struct NCDInterpModuleGroup *group)
+{
+    struct global *g = group->group_state;
+    ASSERT(LinkedList1_IsEmpty(&g->free_depends))
+    ASSERT(LinkedList1_IsEmpty(&g->provides))
+    
+    // free global state structure
+    BFree(g);
+}
+
 static void provide_func_new_templ (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int event)
 {
+    struct global *g = ModuleGlobal(i);
     struct provide *o = vo;
     o->i = i;
     
@@ -189,7 +215,7 @@ static void provide_func_new_templ (void *vo, NCDModuleInst *i, const struct NCD
     NCDModuleInst_Backend_Up(o->i);
     
     // check for existing provide with this name
-    struct provide *ep = find_provide(o->name, o->name_len);
+    struct provide *ep = find_provide(g, o->name, o->name_len);
     if (ep) {
         ASSERT(!ep->is_queued)
         
@@ -229,6 +255,7 @@ static void provide_event_func_new (void *vo, NCDModuleInst *i, const struct NCD
 
 static void provide_free (struct provide *o)
 {
+    struct global *g = ModuleGlobal(o->i);
     ASSERT(o->is_queued || LinkedList1_IsEmpty(&o->depends))
     
     if (o->is_queued) {
@@ -236,7 +263,7 @@ static void provide_free (struct provide *o)
         LinkedList3Node_Free(&o->queued_node);
     } else {
         // remove from provides list
-        LinkedList1_Remove(&provides, &o->provides_node);
+        LinkedList1_Remove(&g->provides, &o->provides_node);
         
         // if we have provides queued, promote the first one
         if (LinkedList3Node_Next(&o->queued_provides_firstnode)) {
@@ -283,6 +310,7 @@ static void provide_func_die (void *vo)
 
 static void depend_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
 {
+    struct global *g = ModuleGlobal(i);
     struct depend *o = vo;
     o->i = i;
     
@@ -300,7 +328,7 @@ static void depend_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleI
     o->name_len = NCDVal_StringLength(name_arg);
     
     // find a provide with our name
-    struct provide *p = find_provide(o->name, o->name_len);
+    struct provide *p = find_provide(g, o->name, o->name_len);
     ASSERT(!p || !p->is_queued)
     
     if (p && !p->dying) {
@@ -314,7 +342,7 @@ static void depend_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleI
         NCDModuleInst_Backend_Up(o->i);
     } else {
         // insert to free depends list
-        LinkedList1_Append(&free_depends, &o->node);
+        LinkedList1_Append(&g->free_depends, &o->node);
         
         // set no provide
         o->p = NULL;
@@ -328,6 +356,7 @@ fail0:
 
 static void depend_free (struct depend *o)
 {
+    struct global *g = ModuleGlobal(o->i);
     ASSERT(!o->p || !o->p->is_queued)
     
     if (o->p) {
@@ -340,7 +369,7 @@ static void depend_free (struct depend *o)
         }
     } else {
         // remove free depends list
-        LinkedList1_Remove(&free_depends, &o->node);
+        LinkedList1_Remove(&g->free_depends, &o->node);
     }
     
     NCDModuleInst_Backend_Dead(o->i);
@@ -356,6 +385,7 @@ static void depend_func_die (void *vo)
 static void depend_func_clean (void *vo)
 {
     struct depend *o = vo;
+    struct global *g = ModuleGlobal(o->i);
     ASSERT(!o->p || !o->p->is_queued)
     
     if (!(o->p && o->p->dying)) {
@@ -368,7 +398,7 @@ static void depend_func_clean (void *vo)
     LinkedList1_Remove(&p->depends, &o->node);
     
     // insert to free depends list
-    LinkedList1_Append(&free_depends, &o->node);
+    LinkedList1_Append(&g->free_depends, &o->node);
     
     // set no provide
     o->p = NULL;
@@ -417,5 +447,6 @@ static struct NCDModule modules[] = {
 
 const struct NCDModuleGroup ncdmodule_depend = {
     .func_globalinit = func_globalinit,
+    .func_globalfree = func_globalfree,
     .modules = modules
 };

+ 42 - 12
ncd/modules/dynamic_depend.c

@@ -41,6 +41,7 @@
 #include <misc/debug.h>
 #include <misc/compare.h>
 #include <misc/strdup.h>
+#include <misc/balloc.h>
 #include <structure/LinkedList0.h>
 #include <structure/BAVL.h>
 #include <ncd/NCDModule.h>
@@ -48,6 +49,7 @@
 #include <generated/blog_channel_ncd_dynamic_depend.h>
 
 #define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__)
+#define ModuleGlobal(i) ((i)->m->group->group_state)
 
 struct provide;
 
@@ -57,6 +59,7 @@ struct name_string {
 };
 
 struct name {
+    struct global *g;
     struct name_string name;
     BAVLNode names_tree_node;
     BAVL provides_tree;
@@ -81,7 +84,9 @@ struct depend {
     LinkedList0Node depends_list_node;
 };
 
-static BAVL names_tree;
+struct global {
+    BAVL names_tree;
+};
 
 static void provide_free (struct provide *o);
 static void depend_free (struct depend *o);
@@ -106,10 +111,10 @@ static int val_comparator (void *user, NCDValRef *v1, NCDValRef *v2)
     return NCDVal_Compare(*v1, *v2);
 }
 
-static struct name * find_name (const char *name, size_t name_len)
+static struct name * find_name (struct global *g, const char *name, size_t name_len)
 {
     struct name_string ns = {(char *)name, name_len};
-    BAVLNode *tn = BAVL_LookupExact(&names_tree, &ns);
+    BAVLNode *tn = BAVL_LookupExact(&g->names_tree, &ns);
     if (!tn) {
         return NULL;
     }
@@ -121,9 +126,9 @@ static struct name * find_name (const char *name, size_t name_len)
     return n;
 }
 
-static struct name * name_init (NCDModuleInst *i, const char *name, size_t name_len)
+static struct name * name_init (NCDModuleInst *i, struct global *g, const char *name, size_t name_len)
 {
-    ASSERT(!find_name(name, name_len))
+    ASSERT(!find_name(g, name, name_len))
     
     // allocate structure
     struct name *o = malloc(sizeof(*o));
@@ -132,6 +137,9 @@ static struct name * name_init (NCDModuleInst *i, const char *name, size_t name_
         goto fail0;
     }
     
+    // set global state
+    o->g = g;
+    
     // copy name
     if (!(o->name.data = b_strdup_bin(name, name_len))) {
         ModuleLog(i, BLOG_ERROR, "strdup failed");
@@ -140,7 +148,7 @@ static struct name * name_init (NCDModuleInst *i, const char *name, size_t name_
     o->name.len = name_len;
     
     // insert to names tree
-    ASSERT_EXECUTE(BAVL_Insert(&names_tree, &o->names_tree_node, NULL))
+    ASSERT_EXECUTE(BAVL_Insert(&g->names_tree, &o->names_tree_node, NULL))
     
     // init provides tree
     BAVL_Init(&o->provides_tree, OFFSET_DIFF(struct provide, order_value, provides_tree_node), (BAVL_comparator)val_comparator, NULL);
@@ -166,7 +174,7 @@ static void name_free (struct name *o)
     ASSERT(!o->cur_p)
     
     // remove from names tree
-    BAVL_Remove(&names_tree, &o->names_tree_node);
+    BAVL_Remove(&o->g->names_tree, &o->names_tree_node);
     
     // free name
     free(o->name.data);
@@ -280,14 +288,34 @@ static void name_start_resetting (struct name *o)
 
 static int func_globalinit (struct NCDInterpModuleGroup *group, const struct NCDModuleInst_iparams *params)
 {
+    // allocate global state structure
+    struct global *g = BAlloc(sizeof(*g));
+    if (!g) {
+        BLog(BLOG_ERROR, "BAlloc failed");
+        return 0;
+    }
+    
+    // set group state pointer
+    group->group_state = g;
+    
     // init names tree
-    BAVL_Init(&names_tree, OFFSET_DIFF(struct name, name, names_tree_node), name_string_comparator, NULL);
+    BAVL_Init(&g->names_tree, OFFSET_DIFF(struct name, name, names_tree_node), name_string_comparator, NULL);
     
     return 1;
 }
 
+static void func_globalfree (struct NCDInterpModuleGroup *group)
+{
+    struct global *g = group->group_state;
+    ASSERT(BAVL_IsEmpty(&g->names_tree))
+    
+    // free global state structure
+    BFree(g);
+}
+
 static void provide_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
 {
+    struct global *g = ModuleGlobal(i);
     struct provide *o = vo;
     o->i = i;
     
@@ -305,8 +333,8 @@ static void provide_func_new (void *vo, NCDModuleInst *i, const struct NCDModule
     size_t name_len = NCDVal_StringLength(name_arg);
     
     // find name, create new if needed
-    struct name *n = find_name(name_str, name_len);
-    if (!n && !(n = name_init(i, name_str, name_len))) {
+    struct name *n = find_name(g, name_str, name_len);
+    if (!n && !(n = name_init(i, g, name_str, name_len))) {
         goto fail0;
     }
     
@@ -383,6 +411,7 @@ static void provide_func_die (void *vo)
 
 static void depend_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
 {
+    struct global *g = ModuleGlobal(i);
     struct depend *o = vo;
     o->i = i;
     
@@ -400,8 +429,8 @@ static void depend_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleI
     size_t name_len = NCDVal_StringLength(name_arg);
     
     // find name, create new if needed
-    struct name *n = find_name(name_str, name_len);
-    if (!n && !(n = name_init(i, name_str, name_len))) {
+    struct name *n = find_name(g, name_str, name_len);
+    if (!n && !(n = name_init(i, g, name_str, name_len))) {
         goto fail0;
     }
     
@@ -514,5 +543,6 @@ static struct NCDModule modules[] = {
 
 const struct NCDModuleGroup ncdmodule_dynamic_depend = {
     .func_globalinit = func_globalinit,
+    .func_globalfree = func_globalfree,
     .modules = modules
 };

+ 44 - 13
ncd/modules/multidepend.c

@@ -72,12 +72,14 @@
 
 #include <misc/offset.h>
 #include <misc/debug.h>
+#include <misc/balloc.h>
 #include <structure/LinkedList1.h>
 #include <ncd/NCDModule.h>
 
 #include <generated/blog_channel_ncd_multidepend.h>
 
 #define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__)
+#define ModuleGlobal(i) ((i)->m->group->group_state)
 
 struct provide {
     NCDModuleInst *i;
@@ -96,12 +98,14 @@ struct depend {
     int provide_collapsing;
 };
 
-static LinkedList1 provides_list;
-static LinkedList1 depends_list;
+struct global {
+    LinkedList1 provides_list;
+    LinkedList1 depends_list;
+};
 
-static struct provide * find_provide (NCDValRef name)
+static struct provide * find_provide (struct global *g, NCDValRef name)
 {
-    for (LinkedList1Node *ln = LinkedList1_GetFirst(&provides_list); ln; ln = LinkedList1Node_Next(ln)) {
+    for (LinkedList1Node *ln = LinkedList1_GetFirst(&g->provides_list); ln; ln = LinkedList1Node_Next(ln)) {
         struct provide *provide = UPPER_OBJECT(ln, struct provide, provides_list_node);
         if (NCDVal_Compare(provide->name, name) == 0) {
             return provide;
@@ -113,11 +117,13 @@ static struct provide * find_provide (NCDValRef name)
 
 static struct provide * depend_find_best_provide (struct depend *o)
 {
+    struct global *g = ModuleGlobal(o->i);
+    
     size_t count = NCDVal_ListCount(o->names);
     
     for (size_t j = 0; j < count; j++) {
         NCDValRef name = NCDVal_ListGet(o->names, j);
-        struct provide *provide = find_provide(name);
+        struct provide *provide = find_provide(g, name);
         if (provide && !provide->dying) {
             return provide;
         }
@@ -165,17 +171,38 @@ static void depend_update (struct depend *o)
 
 static int func_globalinit (struct NCDInterpModuleGroup *group, const struct NCDModuleInst_iparams *params)
 {
+    // allocate global state structure
+    struct global *g = BAlloc(sizeof(*g));
+    if (!g) {
+        BLog(BLOG_ERROR, "BAlloc failed");
+        return 0;
+    }
+    
+    // set group state pointer
+    group->group_state = g;
+    
     // init provides list
-    LinkedList1_Init(&provides_list);
+    LinkedList1_Init(&g->provides_list);
     
     // init depends list
-    LinkedList1_Init(&depends_list);
+    LinkedList1_Init(&g->depends_list);
     
     return 1;
 }
 
+static void func_globalfree (struct NCDInterpModuleGroup *group)
+{
+    struct global *g = group->group_state;
+    ASSERT(LinkedList1_IsEmpty(&g->depends_list))
+    ASSERT(LinkedList1_IsEmpty(&g->provides_list))
+    
+    // free global state structure
+    BFree(g);
+}
+
 static void provide_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
 {
+    struct global *g = ModuleGlobal(i);
     struct provide *o = vo;
     o->i = i;
     
@@ -190,13 +217,13 @@ static void provide_func_new (void *vo, NCDModuleInst *i, const struct NCDModule
     o->name = name_arg;
     
     // check for existing provide with this name
-    if (find_provide(o->name)) {
+    if (find_provide(g, o->name)) {
         ModuleLog(o->i, BLOG_ERROR, "a provide with this name already exists");
         goto fail0;
     }
     
     // insert to provides list
-    LinkedList1_Append(&provides_list, &o->provides_list_node);
+    LinkedList1_Append(&g->provides_list, &o->provides_list_node);
     
     // init depends list
     LinkedList1_Init(&o->depends_list);
@@ -210,7 +237,7 @@ static void provide_func_new (void *vo, NCDModuleInst *i, const struct NCDModule
     NCDModuleInst_Backend_Up(o->i);
     
     // update depends
-    for (LinkedList1Node *ln = LinkedList1_GetFirst(&depends_list); ln; ln = LinkedList1Node_Next(ln)) {
+    for (LinkedList1Node *ln = LinkedList1_GetFirst(&g->depends_list); ln; ln = LinkedList1Node_Next(ln)) {
         struct depend *depend = UPPER_OBJECT(ln, struct depend, depends_list_node);
         depend_update(depend);
     }
@@ -223,10 +250,11 @@ fail0:
 
 static void provide_free (struct provide *o)
 {
+    struct global *g = ModuleGlobal(o->i);
     ASSERT(LinkedList1_IsEmpty(&o->depends_list))
     
     // remove from provides list
-    LinkedList1_Remove(&provides_list, &o->provides_list_node);
+    LinkedList1_Remove(&g->provides_list, &o->provides_list_node);
     
     NCDModuleInst_Backend_Dead(o->i);
 }
@@ -257,6 +285,7 @@ static void provide_func_die (void *vo)
 
 static void depend_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
 {
+    struct global *g = ModuleGlobal(i);
     struct depend *o = vo;
     o->i = i;
     
@@ -275,7 +304,7 @@ static void depend_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleI
     o->names = names_arg;
     
     // insert to depends list
-    LinkedList1_Append(&depends_list, &o->depends_list_node);
+    LinkedList1_Append(&g->depends_list, &o->depends_list_node);
     
     // set no provide
     o->provide = NULL;
@@ -291,6 +320,7 @@ fail0:
 static void depend_func_die (void *vo)
 {
     struct depend *o = vo;
+    struct global *g = ModuleGlobal(o->i);
     
     if (o->provide) {
         // remove from provide's list
@@ -303,7 +333,7 @@ static void depend_func_die (void *vo)
     }
     
     // remove from depends list
-    LinkedList1_Remove(&depends_list, &o->depends_list_node);
+    LinkedList1_Remove(&g->depends_list, &o->depends_list_node);
     
     NCDModuleInst_Backend_Dead(o->i);
 }
@@ -366,5 +396,6 @@ static struct NCDModule modules[] = {
 
 const struct NCDModuleGroup ncdmodule_multidepend = {
     .func_globalinit = func_globalinit,
+    .func_globalfree = func_globalfree,
     .modules = modules
 };

+ 38 - 12
ncd/modules/net_dns.c

@@ -49,6 +49,7 @@
 #include <generated/blog_channel_ncd_net_dns.h>
 
 #define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__)
+#define ModuleGlobal(i) ((i)->m->group->group_state)
 
 struct instance {
     NCDModuleInst *i;
@@ -62,7 +63,9 @@ struct ipv4_dns_entry {
     int priority;
 };
 
-static LinkedList1 instances;
+struct global {
+    LinkedList1 instances;
+};
 
 static struct ipv4_dns_entry * add_ipv4_dns_entry (struct instance *o, uint32_t addr, int priority)
 {
@@ -100,11 +103,11 @@ static void remove_ipv4_dns_entries (struct instance *o)
     }
 }
 
-static size_t num_servers (void)
+static size_t num_servers (struct global *g)
 {
     size_t c = 0;
     
-    for (LinkedList1Node *n = LinkedList1_GetFirst(&instances); n; n = LinkedList1Node_Next(n)) {
+    for (LinkedList1Node *n = LinkedList1_GetFirst(&g->instances); n; n = LinkedList1Node_Next(n)) {
         struct instance *o = UPPER_OBJECT(n, struct instance, instances_node);
         for (LinkedList1Node *en = LinkedList1_GetFirst(&o->ipv4_dns_servers); en; en = LinkedList1Node_Next(en)) {
             c++;
@@ -126,12 +129,12 @@ static int dns_sort_comparator (const void *v1, const void *v2)
     return B_COMPARE(e1->priority, e2->priority);
 }
 
-static int set_servers (void)
+static int set_servers (struct global *g)
 {
     int ret = 0;
     
     // count servers
-    size_t num_ipv4_dns_servers = num_servers();
+    size_t num_ipv4_dns_servers = num_servers(g);
     
     // allocate sort array
     struct dns_sort_entry *servers = BAllocArray(num_ipv4_dns_servers, sizeof(servers[0]));
@@ -141,7 +144,7 @@ static int set_servers (void)
     size_t num_servers = 0;
     
     // fill sort array
-    for (LinkedList1Node *n = LinkedList1_GetFirst(&instances); n; n = LinkedList1Node_Next(n)) {
+    for (LinkedList1Node *n = LinkedList1_GetFirst(&g->instances); n; n = LinkedList1Node_Next(n)) {
         struct instance *o = UPPER_OBJECT(n, struct instance, instances_node);
         for (LinkedList1Node *en = LinkedList1_GetFirst(&o->ipv4_dns_servers); en; en = LinkedList1Node_Next(en)) {
             struct ipv4_dns_entry *e = UPPER_OBJECT(en, struct ipv4_dns_entry, list_node);
@@ -183,13 +186,34 @@ fail0:
 
 static int func_globalinit (struct NCDInterpModuleGroup *group, const struct NCDModuleInst_iparams *params)
 {
-    LinkedList1_Init(&instances);
+    // allocate global state structure
+    struct global *g = BAlloc(sizeof(*g));
+    if (!g) {
+        BLog(BLOG_ERROR, "BAlloc failed");
+        return 0;
+    }
+    
+    // set group state pointer
+    group->group_state = g;
+    
+    // init instances list
+    LinkedList1_Init(&g->instances);
     
     return 1;
 }
 
+static void func_globalfree (struct NCDInterpModuleGroup *group)
+{
+    struct global *g = group->group_state;
+    ASSERT(LinkedList1_IsEmpty(&g->instances))
+    
+    // free global state structure
+    BFree(g);
+}
+
 static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
 {
+    struct global *g = ModuleGlobal(i);
     struct instance *o = vo;
     o->i = i;
     
@@ -237,10 +261,10 @@ static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new
     }
     
     // add to instances
-    LinkedList1_Append(&instances, &o->instances_node);
+    LinkedList1_Append(&g->instances, &o->instances_node);
     
     // set servers
-    if (!set_servers()) {
+    if (!set_servers(g)) {
         ModuleLog(o->i, BLOG_ERROR, "failed to set DNS servers");
         goto fail2;
     }
@@ -250,7 +274,7 @@ static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new
     return;
     
 fail2:
-    LinkedList1_Remove(&instances, &o->instances_node);
+    LinkedList1_Remove(&g->instances, &o->instances_node);
 fail1:
     remove_ipv4_dns_entries(o);
     NCDModuleInst_Backend_DeadError(i);
@@ -259,12 +283,13 @@ fail1:
 static void func_die (void *vo)
 {
     struct instance *o = vo;
+    struct global *g = ModuleGlobal(o->i);
     
     // remove from instances
-    LinkedList1_Remove(&instances, &o->instances_node);
+    LinkedList1_Remove(&g->instances, &o->instances_node);
     
     // set servers
-    set_servers();
+    set_servers(g);
     
     // free servers
     remove_ipv4_dns_entries(o);
@@ -285,5 +310,6 @@ static struct NCDModule modules[] = {
 
 const struct NCDModuleGroup ncdmodule_net_dns = {
     .func_globalinit = func_globalinit,
+    .func_globalfree = func_globalfree,
     .modules = modules
 };

+ 26 - 5
ncd/modules/net_iptables.c

@@ -98,6 +98,7 @@
 
 #include <misc/debug.h>
 #include <misc/find_program.h>
+#include <misc/balloc.h>
 #include <ncd/extra/BEventLock.h>
 
 #include <ncd/modules/command_template.h>
@@ -105,10 +106,13 @@
 #include <generated/blog_channel_ncd_net_iptables.h>
 
 #define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__)
+#define ModuleGlobal(i) ((i)->m->group->group_state)
 
 static void template_free_func (void *vo, int is_error);
 
-static BEventLock iptables_lock;
+struct global {
+    BEventLock iptables_lock;
+};
 
 struct instance {
     NCDModuleInst *i;
@@ -381,24 +385,40 @@ static void lock_job_handler (struct lock_instance *o)
 
 static int func_globalinit (struct NCDInterpModuleGroup *group, const struct NCDModuleInst_iparams *params)
 {
+    // allocate global state structure
+    struct global *g = BAlloc(sizeof(*g));
+    if (!g) {
+        BLog(BLOG_ERROR, "BAlloc failed");
+        return 0;
+    }
+    
+    // set group state pointer
+    group->group_state = g;
+    
     // init iptables lock
-    BEventLock_Init(&iptables_lock, BReactor_PendingGroup(params->reactor));
+    BEventLock_Init(&g->iptables_lock, BReactor_PendingGroup(params->reactor));
     
     return 1;
 }
 
 static void func_globalfree (struct NCDInterpModuleGroup *group)
 {
+    struct global *g = group->group_state;
+    
     // free iptables lock
-    BEventLock_Free(&iptables_lock);
+    BEventLock_Free(&g->iptables_lock);
+    
+    // free global state structure
+    BFree(g);
 }
 
 static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, command_template_build_cmdline build_cmdline)
 {
+    struct global *g = ModuleGlobal(i);
     struct instance *o = vo;
     o->i = i;
     
-    command_template_new(&o->cti, i, params, build_cmdline, template_free_func, o, BLOG_CURRENT_CHANNEL, &iptables_lock);
+    command_template_new(&o->cti, i, params, build_cmdline, template_free_func, o, BLOG_CURRENT_CHANNEL, &g->iptables_lock);
 }
 
 void template_free_func (void *vo, int is_error)
@@ -451,11 +471,12 @@ static void func_die (void *vo)
 
 static void lock_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
 {
+    struct global *g = ModuleGlobal(i);
     struct lock_instance *o = vo;
     o->i = i;
     
     // init lock job
-    BEventLockJob_Init(&o->lock_job, &iptables_lock, (BEventLock_handler)lock_job_handler, o);
+    BEventLockJob_Init(&o->lock_job, &g->iptables_lock, (BEventLock_handler)lock_job_handler, o);
     BEventLockJob_Wait(&o->lock_job);
     
     // set no unlock