[sr-dev] git:master: cfg framework: fix shutdown crash for non registered modules

Andrei Pelinescu-Onciul andrei at iptel.org
Tue Oct 6 12:46:33 CEST 2009


Module: sip-router
Branch: master
Commit: 5c323052cc0a84d8a7c98ffe0354071dc00be23f
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=5c323052cc0a84d8a7c98ffe0354071dc00be23f

Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at iptel.org>
Date:   Tue Oct  6 12:47:14 2009 +0200

cfg framework: fix shutdown crash for non registered modules

Added cfg_update_no_cbs() which partially updates (no per-child
 callbacks are called) the local config.
It's needed for config update on exit (SIGTERM) for modules that
do not register as cfg users and when the code is compiled with
SIG_DEBUG.

---

 cfg/cfg_struct.h |   18 +++++++++++++++---
 main.c           |    6 +++++-
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/cfg/cfg_struct.h b/cfg/cfg_struct.h
index 0eafc51..0be608e 100644
--- a/cfg/cfg_struct.h
+++ b/cfg/cfg_struct.h
@@ -219,8 +219,10 @@ static inline void cfg_block_free(cfg_block_t *block)
 /* updates all the module handles and calls the
  * per-child process callbacks -- not intended to be used
  * directly, use cfg_update() instead!
+ * params:
+ *   no_cbs - if 1, do not call per child callbacks
  */
-static inline void cfg_update_local(void)
+static inline void cfg_update_local(int no_cbs)
 {
 	cfg_group_t	*group;
 	cfg_child_cb_t	*last_cb;
@@ -247,7 +249,7 @@ static inline void cfg_update_local(void)
 	)
 		*(group->handle) = cfg_local->vars + group->offset;
 
-	if (unlikely(cfg_child_cb==CFG_NO_CHILD_CBS))
+	if (unlikely(cfg_child_cb==CFG_NO_CHILD_CBS || no_cbs))
 		return;
 	/* call the per-process callbacks */
 	while (cfg_child_cb != last_cb) {
@@ -287,7 +289,17 @@ static inline void cfg_update_local(void)
 #define cfg_update() \
 	do { \
 		if (unlikely(cfg_local != *cfg_global)) \
-			cfg_update_local(); \
+			cfg_update_local(0); \
+	} while(0)
+
+/* like cfg_update(), but does not execute callbacks
+ * (it should be used sparingly only in special cases, since it
+ *  breaks an important cfg framework feature)
+ */
+#define cfg_update_no_cbs() \
+	do { \
+		if (unlikely(cfg_local != *cfg_global)) \
+			cfg_update_local(1); \
 	} while(0)
 
 /* searches a group by name */
diff --git a/main.c b/main.c
index 47d8ccc..fb9ba93 100644
--- a/main.c
+++ b/main.c
@@ -779,7 +779,11 @@ void sig_usr(int signo)
 					LOG(L_INFO, "INFO: signal %d received\n", signo);
 					/* print memory stats for non-main too */
 					#ifdef PKG_MALLOC
-					cfg_update(); /* make sure we have current values */
+					/* make sure we have current cfg values, but update only
+					  the safe part (values not requiring callbacks), to
+					  account for processes that might not have registered
+					  config support */
+					cfg_update_no_cbs();
 					memlog=cfg_get(core, core_cfg, memlog);
 					if (memlog <= cfg_get(core, core_cfg, debug)){
 						if (cfg_get(core, core_cfg, mem_summary) & 1) {




More information about the sr-dev mailing list