From 42ddcf0419e9c96610f98ec07030df41dd101208 Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Wed, 31 May 2023 14:17:47 +1100
Subject: [PATCH] avoid extra callback and nested loop

---
 src/include/66/service.h                   |   2 +-
 src/lib66/exec/ssexec_disable.c            |   6 +-
 src/lib66/exec/ssexec_enable.c             |   6 +-
 src/lib66/service/service_enable_disable.c | 106 +++++++++++----------
 4 files changed, 64 insertions(+), 56 deletions(-)

diff --git a/src/include/66/service.h b/src/include/66/service.h
index 4776b330..a064ebc1 100644
--- a/src/include/66/service.h
+++ b/src/include/66/service.h
@@ -315,7 +315,7 @@ extern int service_resolve_read_cdb(cdb *c, resolve_service_t *res) ;
 extern void service_resolve_write(resolve_service_t *res) ;
 extern void service_resolve_write_tmp(resolve_service_t *res, char const *dst, uint8_t force) ;
 extern int service_resolve_write_cdb(cdbmaker *c, resolve_service_t *sres) ;
-extern void service_enable_disable(graph_t *g, resolve_service_t *res, resolve_service_t *ares, unsigned int areslen, uint8_t action, visit_t *visit) ;
+extern void service_enable_disable(graph_t *g, unsigned int idx, resolve_service_t *ares, unsigned int areslen, uint8_t action, visit_t *visit) ;
 /* avoid circular dependencies by prototyping the ss_state_t instead
  * of calling the state.h header file*/
 typedef struct ss_state_s ss_state_t, *ss_state_t_ref ;
diff --git a/src/lib66/exec/ssexec_disable.c b/src/lib66/exec/ssexec_disable.c
index d0313c08..f0b2640d 100644
--- a/src/lib66/exec/ssexec_disable.c
+++ b/src/lib66/exec/ssexec_disable.c
@@ -44,9 +44,9 @@ int ssexec_disable(int argc, char const *const *argv, ssexec_t *info)
     stralloc sa = STRALLOC_ZERO ;
 
     unsigned int areslen = 0 ;
-    resolve_service_t ares[SS_MAX_SERVICE] ;
+    resolve_service_t ares[SS_MAX_SERVICE + 1] ;
 
-    visit_t visit[SS_MAX_SERVICE] ;
+    visit_t visit[SS_MAX_SERVICE + 1] ;
     visit_init(visit, SS_MAX_SERVICE) ;
 
     FLAGS_SET(flag, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_WANTUP) ;
@@ -105,7 +105,7 @@ int ssexec_disable(int argc, char const *const *argv, ssexec_t *info)
         if (aresid < 0)
             log_die(LOG_EXIT_USER, "service: ", argv[n], " not available -- did you parsed it?") ;
 
-        service_enable_disable(&graph, &ares[aresid], ares, areslen, 0, visit) ;
+        service_enable_disable(&graph, aresid, ares, areslen, 0, visit) ;
 
         if (!sastr_add_string(&sa, argv[n]))
             log_dieu(LOG_EXIT_SYS, "add string") ;
diff --git a/src/lib66/exec/ssexec_enable.c b/src/lib66/exec/ssexec_enable.c
index 8c8f54a3..3d935909 100644
--- a/src/lib66/exec/ssexec_enable.c
+++ b/src/lib66/exec/ssexec_enable.c
@@ -65,9 +65,9 @@ int ssexec_enable(int argc, char const *const *argv, ssexec_t *info)
     stralloc sa = STRALLOC_ZERO ;
 
     unsigned int areslen = 0 ;
-    resolve_service_t ares[SS_MAX_SERVICE] ;
+    resolve_service_t ares[SS_MAX_SERVICE + 1] ;
 
-    visit_t visit[SS_MAX_SERVICE] ;
+    visit_t visit[SS_MAX_SERVICE + 1] ;
     visit_init(visit, SS_MAX_SERVICE) ;
 
     FLAGS_SET(flag, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_WANTUP) ;
@@ -132,7 +132,7 @@ int ssexec_enable(int argc, char const *const *argv, ssexec_t *info)
         if (aresid < 0)
             log_die(LOG_EXIT_USER, "service: ", argv[n], " not available -- did you parsed it?") ;
 
-        service_enable_disable(&graph, &ares[aresid], ares, areslen, 1, visit) ;
+        service_enable_disable(&graph, aresid, ares, areslen, 1, visit) ;
 
         if (!sastr_add_string(&sa, argv[n]))
             log_dieu(LOG_EXIT_SYS, "add string") ;
diff --git a/src/lib66/service/service_enable_disable.c b/src/lib66/service/service_enable_disable.c
index 8f87a54a..6cb6022c 100644
--- a/src/lib66/service/service_enable_disable.c
+++ b/src/lib66/service/service_enable_disable.c
@@ -26,12 +26,13 @@
 #include <66/utils.h>
 #include <66/enum.h>
 
-static void service_enable_disable_deps(graph_t *g, resolve_service_t *res, resolve_service_t *ares, unsigned int areslen, uint8_t action, visit_t *visit)
+static void service_enable_disable_deps(graph_t *g, unsigned int idx, resolve_service_t *ares, unsigned int areslen, uint8_t action, visit_t *visit)
 {
     log_flow() ;
 
-    size_t pos = 0, element = 0 ;
+    size_t pos = 0 ;
     stralloc sa = STRALLOC_ZERO ;
+    resolve_service_t_ref res = &ares[idx] ;
 
     if (graph_matrix_get_edge_g_sa(&sa, g, res->sa.s + res->name, action ? 0 : 1, 0) < 0)
         log_dieu(LOG_EXIT_SYS, "get ", action ? "dependencies" : "required by" ," of: ", res->sa.s + res->name) ;
@@ -40,18 +41,13 @@ static void service_enable_disable_deps(graph_t *g, resolve_service_t *res, reso
 
         FOREACH_SASTR(&sa, pos) {
 
-            if (visit[element] == VISIT_WHITE) {
+            char *name = sa.s + pos ;
+            int aresid = service_resolve_array_search(ares, areslen, name) ;
+            if (aresid < 0)
+                log_die(LOG_EXIT_USER, "service: ", name, " not available -- did you parsed it?") ;
 
-                char *name = sa.s + pos ;
-                int aresid = service_resolve_array_search(ares, areslen, name) ;
-                if (aresid < 0)
-                    log_die(LOG_EXIT_USER, "service: ", name, " not available -- did you parsed it?") ;
-
-                service_enable_disable(g, &ares[aresid], ares, areslen, action, visit) ;
-
-                visit[element] = VISIT_GRAY ;
-            }
-            element++ ;
+            if (visit[aresid] == VISIT_WHITE)
+                service_enable_disable(g, aresid, ares, areslen, action, visit) ;
         }
     }
 
@@ -60,64 +56,76 @@ static void service_enable_disable_deps(graph_t *g, resolve_service_t *res, reso
 
 /** @action -> 0 disable
  * @action -> 1 enable */
-void service_enable_disable(graph_t *g, resolve_service_t *res, resolve_service_t *ares, unsigned int areslen, uint8_t action, visit_t *visit)
+void service_enable_disable(graph_t *g, unsigned int idx, resolve_service_t *ares, unsigned int areslen, uint8_t action, visit_t *visit)
 {
     log_flow() ;
 
-    if (!state_messenger(res, STATE_FLAGS_ISENABLED, !action ? STATE_FLAGS_FALSE : STATE_FLAGS_TRUE))
-        log_dieusys(LOG_EXIT_SYS, "send message to state of: ", res->sa.s + res->name) ;
+    if (visit[idx] == VISIT_WHITE) {
 
-    service_enable_disable_deps(g, res, ares, areslen, action, visit) ;
+        resolve_service_t_ref res = &ares[idx] ;
 
-    /** the logger must be disabled to avoid to start it
-     * with the 66 tree start <tree> command */
-    if (res->logger.want && !action) {
+        if (!state_messenger(res, STATE_FLAGS_ISENABLED, !action ? STATE_FLAGS_FALSE : STATE_FLAGS_TRUE))
+            log_dieusys(LOG_EXIT_SYS, "send message to state of: ", res->sa.s + res->name) ;
 
-        char *name = res->sa.s + res->logger.name ;
+        service_enable_disable_deps(g, idx, ares, areslen, action, visit) ;
 
-        int aresid = service_resolve_array_search(ares, areslen, name) ;
-        if (aresid < 0)
-            log_die(LOG_EXIT_USER, "service: ", name, " not available -- did you parsed it?") ;
+        /** the logger must be disabled to avoid to start it
+         * with the 66 tree start <tree> command */
+        if (res->logger.want && !action && res->type == TYPE_CLASSIC && !res->inmodule) {
 
-        if (!state_messenger(&ares[aresid], STATE_FLAGS_ISENABLED, !action ? STATE_FLAGS_FALSE : STATE_FLAGS_TRUE))
-            log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ;
+            char *name = res->sa.s + res->logger.name ;
 
-        log_info("Disabled successfully service: ", name) ;
+            int aresid = service_resolve_array_search(ares, areslen, name) ;
+            if (aresid < 0)
+                log_die(LOG_EXIT_USER, "service: ", name, " not available -- did you parsed it?") ;
 
-    }
+            if (visit[aresid] == VISIT_WHITE) {
 
-    if (res->type == TYPE_MODULE || res->type == TYPE_BUNDLE) {
+                if (!state_messenger(&ares[aresid], STATE_FLAGS_ISENABLED, !action ? STATE_FLAGS_FALSE : STATE_FLAGS_TRUE))
+                    log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ;
 
-        if (res->dependencies.ncontents) {
+                log_info("Disabled successfully service: ", name) ;
 
-            size_t pos = 0 ;
-            stralloc sa = STRALLOC_ZERO ;
+                visit[aresid] = VISIT_GRAY ;
+            }
+        }
 
-            visit_t mvisit[SS_MAX_SERVICE] ;
-            visit_init(mvisit, SS_MAX_SERVICE) ;
+        if (res->type == TYPE_MODULE || res->type == TYPE_BUNDLE) {
 
-            if (!sastr_clean_string(&sa, res->sa.s + res->dependencies.contents))
-                log_dieu(LOG_EXIT_SYS, "clean string") ;
+            if (res->dependencies.ncontents) {
 
-            FOREACH_SASTR(&sa, pos) {
+                size_t pos = 0 ;
+                stralloc sa = STRALLOC_ZERO ;
 
-                char *name = sa.s + pos ;
-                int aresid = service_resolve_array_search(ares, areslen, name) ;
-                if (aresid < 0)
-                    log_die(LOG_EXIT_USER, "service: ", name, " not available -- did you parsed it?") ;
+                if (!sastr_clean_string(&sa, res->sa.s + res->dependencies.contents))
+                    log_dieu(LOG_EXIT_SYS, "clean string") ;
 
-                if (!state_messenger(&ares[aresid], STATE_FLAGS_ISENABLED, !action ? STATE_FLAGS_FALSE : STATE_FLAGS_TRUE))
-                    log_dieusys(LOG_EXIT_SYS, "send message to state of: ", res->sa.s + res->name) ;
+                FOREACH_SASTR(&sa, pos) {
 
-                service_enable_disable_deps(g, &ares[aresid], ares, areslen, action, mvisit) ;
+                    char *name = sa.s + pos ;
+                    int aresid = service_resolve_array_search(ares, areslen, name) ;
+                    if (aresid < 0)
+                        log_die(LOG_EXIT_USER, "service: ", name, " not available -- did you parsed it?") ;
 
-                log_info(!action ? "Disabled" : "Enabled"," successfully service: ", ares[aresid].sa.s + ares[aresid].name) ;
-            }
+                    if (visit[aresid] == VISIT_WHITE) {
+
+                        if (!state_messenger(&ares[aresid], STATE_FLAGS_ISENABLED, !action ? STATE_FLAGS_FALSE : STATE_FLAGS_TRUE))
+                            log_dieusys(LOG_EXIT_SYS, "send message to state of: ", res->sa.s + res->name) ;
+
+                        service_enable_disable_deps(g, aresid, ares, areslen, action, visit) ;
+
+                        visit[aresid] = VISIT_GRAY ;
 
-            stralloc_free(&sa) ;
+                        log_info(!action ? "Disabled" : "Enabled"," successfully service: ", ares[aresid].sa.s + ares[aresid].name) ;
+                    }
+                }
+
+                stralloc_free(&sa) ;
+            }
         }
-    }
 
-    log_info(!action ? "Disabled" : "Enabled"," successfully service: ", res->sa.s + res->name) ;
+        visit[idx] = VISIT_GRAY ;
 
+        log_info(!action ? "Disabled" : "Enabled"," successfully service: ", res->sa.s + res->name) ;
+    }
 }
-- 
GitLab