<p>neels has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/15661">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">add osmo_fsm_inst_dispatch_and_watch()<br><br>The most common use case for osmo_fsm_inst_watch() is to dispatch an event and<br>determine whether that caused deallocation. Add this convenience wrapper to<br>simplify implementing this use case.<br><br>This:<br><br>   void event_action()<br>   {<br>           struct osmo_fsm_inst_watcher watch_bar;<br><br>           osmo_fsm_inst_watch(&watch_bar, bar);<br>           osmo_fsm_inst_dispatch(foo, FOO_EVENT, NULL);<br>           osmo_fsm_inst_unwatch(&watch_bar);<br><br>           if (watch_bar.exists)<br>                   osmo_fsm_inst_dispatch(bar, BAR_EVENT, NULL);<br>   }<br><br>becomes:<br><br>   void event_action()<br>   {<br>           if (osmo_fsm_inst_dispatch_and_watch(foo, FOO_EVENT, NULL,<br>                                               bar, NULL))<br>                   osmo_fsm_inst_dispatch(bar, BAR_EVENT, NULL);<br>   }<br><br>Change-Id: Ie9a77783d2052d4677fc5d0a7eb15f9e3b0fda8f<br>---<br>M include/osmocom/core/fsm.h<br>M src/fsm.c<br>2 files changed, 41 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/61/15661/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/core/fsm.h b/include/osmocom/core/fsm.h</span><br><span>index 2487124..8e9ed77 100644</span><br><span>--- a/include/osmocom/core/fsm.h</span><br><span>+++ b/include/osmocom/core/fsm.h</span><br><span>@@ -301,6 +301,20 @@</span><br><span> int _osmo_fsm_inst_dispatch(struct osmo_fsm_inst *fi, uint32_t event, void *data,</span><br><span>                      const char *file, int line);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! dispatch an event to an FSM instance, while watching out for deallocation of this or another instance.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This is a convenience wrapper for using osmo_fsm_inst_watch() and osmo_fsm_inst_dispatch().</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This is a macro that calls _osmo_fsm_inst_dispatch_and_watch() with the given</span><br><span style="color: hsl(120, 100%, 40%);">+ * parameters as well as the caller's source file and line number for logging</span><br><span style="color: hsl(120, 100%, 40%);">+ * purposes. See there for documentation.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#define osmo_fsm_inst_dispatch_and_watch(fi, event, data, watch_fi, rc_p) \</span><br><span style="color: hsl(120, 100%, 40%);">+    _osmo_fsm_inst_dispatch_and_watch(fi, event, data, watch_fi, rc_p, __FILE__, __LINE__)</span><br><span style="color: hsl(120, 100%, 40%);">+bool _osmo_fsm_inst_dispatch_and_watch(struct osmo_fsm_inst *fi, uint32_t event, void *data,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 struct osmo_fsm_inst *watch_fi, int *rc_p,</span><br><span style="color: hsl(120, 100%, 40%);">+                                    const char *file, int line);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! Terminate FSM instance with given cause</span><br><span>  *</span><br><span>  *  This is a macro that calls _osmo_fsm_inst_term() with the given parameters</span><br><span>diff --git a/src/fsm.c b/src/fsm.c</span><br><span>index 03f22cb..526a7ad 100644</span><br><span>--- a/src/fsm.c</span><br><span>+++ b/src/fsm.c</span><br><span>@@ -836,6 +836,33 @@</span><br><span>         return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! dispatch an event to an FSM instance, while watching out for deallocation of this or another instance.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ *  This is a convenience wrapper for using osmo_fsm_inst_watch() and osmo_fsm_inst_dispatch().</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] fi  FSM instance to dispatch event to.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] event  Event to dispatch.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] data  Data to pass along with the event.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] watch_fi  FSM instance to watch deallocation of (possibly but not necessarily identical to fi).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] rc_p  If not NULL, return the _osmo_fsm_inst_dispatch() return value in this int.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] file  Calling source file (from osmo_fsm_inst_dispatch macro)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] line  Calling source line (from osmo_fsm_inst_dispatch macro)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns true if watch_fi still exists after dispatching the event, false if it was deallocated or was NULL.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+bool _osmo_fsm_inst_dispatch_and_watch(struct osmo_fsm_inst *fi, uint32_t event, void *data,</span><br><span style="color: hsl(120, 100%, 40%);">+                                struct osmo_fsm_inst *watch_fi, int *rc_p,</span><br><span style="color: hsl(120, 100%, 40%);">+                                    const char *file, int line)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct osmo_fsm_inst_watcher watcher;</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fsm_inst_watch(&watcher, watch_fi);</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = _osmo_fsm_inst_dispatch(fi, event, data, file, line);</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_fsm_inst_unwatch(&watcher);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rc_p)</span><br><span style="color: hsl(120, 100%, 40%);">+             *rc_p = rc;</span><br><span style="color: hsl(120, 100%, 40%);">+   return watcher.exists;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! Terminate FSM instance with given cause</span><br><span>  *</span><br><span>  *  This safely terminates the given FSM instance by first iterating</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/15661">change 15661</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmocore/+/15661"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ie9a77783d2052d4677fc5d0a7eb15f9e3b0fda8f </div>
<div style="display:none"> Gerrit-Change-Number: 15661 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>