Просмотр исходного кода

ncd: add module option to allow the interpreter to resolve variables and object in the module even when it's down

ambrop7 14 лет назад
Родитель
Сommit
2beb36614b
3 измененных файлов с 33 добавлено и 14 удалено
  1. 18 4
      ncd/NCDModule.c
  2. 9 4
      ncd/NCDModule.h
  3. 6 6
      ncd/ncd.c

+ 18 - 4
ncd/NCDModule.c

@@ -245,13 +245,28 @@ void NCDModuleInst_Clean (NCDModuleInst *n)
     }
 }
 
+static int can_resolve (NCDModuleInst *n)
+{
+    switch (n->state) {
+        case STATE_UP:
+        case STATE_UP_DIE:
+            return 1;
+        case STATE_DOWN_CLEAN:
+        case STATE_DOWN_UNCLEAN:
+        case STATE_DOWN_PCLEAN:
+        case STATE_DOWN_DIE:
+            return n->m->can_resolve_when_down;
+        default:
+            return 0;
+    }
+}
+
 int NCDModuleInst_GetVar (NCDModuleInst *n, const char *name, NCDValue *out)
 {
     DebugObject_Access(&n->d_obj);
-    ASSERT(n->state == STATE_UP)
     ASSERT(name)
     
-    if (!n->m->func_getvar) {
+    if (!n->m->func_getvar || !can_resolve(n)) {
         return 0;
     }
     
@@ -261,10 +276,9 @@ int NCDModuleInst_GetVar (NCDModuleInst *n, const char *name, NCDValue *out)
 NCDModuleInst * NCDModuleInst_GetObj (NCDModuleInst *n, const char *name)
 {
     DebugObject_Access(&n->d_obj);
-    ASSERT(n->state == STATE_UP)
     ASSERT(name)
     
-    if (!n->m->func_getobj) {
+    if (!n->m->func_getobj || !can_resolve(n)) {
         return NULL;
     }
     

+ 9 - 4
ncd/NCDModule.h

@@ -331,7 +331,6 @@ void NCDModuleInst_Clean (NCDModuleInst *n);
 
 /**
  * Resolves a variable within the instance.
- * The instance must be in up state.
  * This function does not have any side effects.
  * 
  * @param n the instance
@@ -343,7 +342,6 @@ int NCDModuleInst_GetVar (NCDModuleInst *n, const char *name, NCDValue *out) WAR
 
 /**
  * Resolves an object within the instance.
- * The instance must be in up state.
  * This function does not have any side effects.
  * 
  * @param n the instance
@@ -625,7 +623,7 @@ typedef void (*NCDModule_func_die) (void *o);
 
 /**
  * Function called to resolve a variable within a backend instance.
- * The backend instance is in up state.
+ * The backend instance is in up state, or in up or down state if can_resolve_when_down=1.
  * This function must not have any side effects.
  * 
  * @param o as in {@link NCDModuleInst_Backend_SetUser}, or NULL by default
@@ -637,7 +635,7 @@ typedef int (*NCDModule_func_getvar) (void *o, const char *name, NCDValue *out);
 
 /**
  * Function called to resolve an object within a backend instance.
- * The backend instance is in up state.
+ * The backend instance is in up state, or in up or down state if can_resolve_when_down=1.
  * This function must not have any side effects.
  * 
  * @param o as in {@link NCDModuleInst_Backend_SetUser}, or NULL by default
@@ -704,6 +702,13 @@ struct NCDModule {
      * May be NULL.
      */
     NCDModule_func_clean func_clean;
+    
+    /**
+     * Whether the interpreter is allowed to call func_getvar and func_getobj
+     * even when the backend instance is in down state (as opposed to just
+     * in up state).
+     */
+    int can_resolve_when_down;
 };
 
 /**

+ 6 - 6
ncd/ncd.c

@@ -1311,9 +1311,9 @@ int process_resolve_variable (struct process *p, size_t pos, const char *varname
         return 0;
     }
     
-    // TODO allow resolving even if not up
-    if (rps->state != SSTATE_ADULT) {
-        process_log(p, BLOG_ERROR, "referred module is not up to resolve variable: %s", varname);
+    // must not be forgotten
+    if (rps->state == SSTATE_FORGOTTEN) {
+        process_log(p, BLOG_ERROR, "referred module is uninitialized and cannot resolve variable: %s", varname);
         return 0;
     }
     
@@ -1354,9 +1354,9 @@ struct process_statement * process_resolve_object (struct process *p, size_t pos
         return NULL;
     }
     
-    // TODO allow resolving even if not up
-    if (rps->state != SSTATE_ADULT) {
-        process_log(p, BLOG_ERROR, "referred module is not up to resolve object: %s", objname);
+    // must not be forgotten
+    if (rps->state == SSTATE_FORGOTTEN) {
+        process_log(p, BLOG_ERROR, "referred module is uninitialized and cannot resolve object: %s", objname);
         return NULL;
     }