[PATCH] libosmocore[master]: fsm: factor out osmo_fsm_inst_term_children() from osmo_fsm_...

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Fri Dec 23 03:46:24 UTC 2016


Review at  https://gerrit.osmocom.org/1496

fsm: factor out osmo_fsm_inst_term_children() from osmo_fsm_inst_term()

osmo_fsm_inst_term() has code for safe child removal, publish that part as
osmo_fsm_inst_term_children(); also use from osmo_fsm_inst_term().

As with osmo_fsm_inst_term(), add osmo_fsm_inst_term_children() macro to pass
the caller's source file and line to new _osmo_fsm_inst_term_children().

Rationale: in openbsc's VLR, I want to discard child FSMs when certain events
are handled. I could keep a pointer to each one, or simply iterate all
children, making the code a lot simpler in some places.

(Unfortunately, the patch may be displayed subobtimally. This really only moves
the children-loop to a new function, replaces it with a call to
_osmo_fsm_inst_term_children(fi, OSMO_FSM_TERM_PARENT, NULL, file, line) and
drops two local iterator variables. No other code changes are made, even though
the diff may show large removal + addition chunks)

Change-Id: I8dac1206259cbd251660f793ad023aaa1dc705a2
---
M include/osmocom/core/fsm.h
M src/fsm.c
2 files changed, 55 insertions(+), 20 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/96/1496/1

diff --git a/include/osmocom/core/fsm.h b/include/osmocom/core/fsm.h
index 8f65533..a2c20b7 100644
--- a/include/osmocom/core/fsm.h
+++ b/include/osmocom/core/fsm.h
@@ -187,4 +187,17 @@
 			 enum osmo_fsm_term_cause cause, void *data,
 			 const char *file, int line);
 
+/*! \brief Terminate all child FSM instances of an FSM instance.
+ *
+ *  This is a macro that calls _osmo_fsm_inst_term_children() with the given
+ *  parameters as well as the caller's source file and line number for logging
+ *  purposes. See there for documentation.
+ */
+#define osmo_fsm_inst_term_children(fi, cause, data) \
+	_osmo_fsm_inst_term_children(fi, cause, data, __BASE_FILE__, __LINE__)
+void _osmo_fsm_inst_term_children(struct osmo_fsm_inst *fi,
+				  enum osmo_fsm_term_cause cause,
+				  void *data,
+				  const char *file, int line);
+
 /*! @} */
diff --git a/src/fsm.c b/src/fsm.c
index 750f016..5c47a44 100644
--- a/src/fsm.c
+++ b/src/fsm.c
@@ -421,12 +421,52 @@
 			 enum osmo_fsm_term_cause cause, void *data,
 			 const char *file, int line)
 {
-	struct osmo_fsm_inst *first_child, *last_seen_first_child;
 	struct osmo_fsm_inst *parent = fi->proc.parent;
 	uint32_t parent_term_event = fi->proc.parent_term_event;
 
 	LOGPFSMSRC(fi, file, line, "Terminating (cause = %s)\n",
 		   osmo_fsm_term_cause_name(cause));
+
+	_osmo_fsm_inst_term_children(fi, OSMO_FSM_TERM_PARENT, NULL,
+				     file, line);
+
+	/* delete ourselves from the parent */
+	if (parent)
+		LOGPFSMSRC(fi, file, line, "Removing from parent %s\n",
+			   osmo_fsm_inst_name(parent));
+	llist_del(&fi->proc.child);
+
+	/* call destructor / clean-up function */
+	if (fi->fsm->cleanup)
+		fi->fsm->cleanup(fi, cause);
+
+	LOGPFSMSRC(fi, file, line, "Freeing instance\n");
+	osmo_fsm_inst_free(fi);
+
+	/* indicate our termination to the parent */
+	if (parent && cause != OSMO_FSM_TERM_PARENT)
+		_osmo_fsm_inst_dispatch(parent, parent_term_event, data,
+					file, line);
+}
+
+/*! \brief Terminate all child FSM instances of an FSM instance.
+ *
+ *  Iterate over all children and send them a termination event, with the given
+ *  cause. Pass OSMO_FSM_TERM_PARENT to avoid dispatching events from the
+ *  terminated child FSMs.
+ *
+ *  \param[in] fi FSM instance that should be cleared of child FSMs
+ *  \param[in] cause Cause / reason for termination (OSMO_FSM_TERM_PARENT)
+ *  \param[in] data Opaque event data to be passed with the parent term events
+ *  \param[in] file Calling source file (from osmo_fsm_inst_term_children macro)
+ *  \param[in] line Calling source line (from osmo_fsm_inst_term_children macro)
+ */
+void _osmo_fsm_inst_term_children(struct osmo_fsm_inst *fi,
+				  enum osmo_fsm_term_cause cause,
+				  void *data,
+				  const char *file, int line)
+{
+	struct osmo_fsm_inst *first_child, *last_seen_first_child;
 
 	/* iterate over all children, starting from the beginning every time:
 	 * terminating an FSM may emit events that cause other FSMs to also
@@ -447,27 +487,9 @@
 		last_seen_first_child = first_child;
 
 		/* terminate child */
-		_osmo_fsm_inst_term(first_child, OSMO_FSM_TERM_PARENT, NULL,
+		_osmo_fsm_inst_term(first_child, cause, data,
 				    file, line);
 	}
-
-	/* delete ourselves from the parent */
-	if (parent)
-		LOGPFSMSRC(fi, file, line, "Removing from parent %s\n",
-			   osmo_fsm_inst_name(parent));
-	llist_del(&fi->proc.child);
-
-	/* call destructor / clean-up function */
-	if (fi->fsm->cleanup)
-		fi->fsm->cleanup(fi, cause);
-
-	LOGPFSMSRC(fi, file, line, "Freeing instance\n");
-	osmo_fsm_inst_free(fi);
-
-	/* indicate our termination to the parent */
-	if (parent && cause != OSMO_FSM_TERM_PARENT)
-		_osmo_fsm_inst_dispatch(parent, parent_term_event, data,
-					file, line);
 }
 
 const struct value_string osmo_fsm_term_cause_names[] = {

-- 
To view, visit https://gerrit.osmocom.org/1496
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I8dac1206259cbd251660f793ad023aaa1dc705a2
Gerrit-PatchSet: 1
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>



More information about the gerrit-log mailing list