Explorar o código

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 %!s(int64=13) %!d(string=hai) anos
pai
achega
1fc023a1e4
Modificáronse 5 ficheiros con 197 adicións e 58 borrados
  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