tnt has uploaded this change for review. ( https://gerrit.osmocom.org/12983


Change subject: [WIP] fsm: Delay processing events after dispatch is complete
......................................................................

[WIP] fsm: Delay processing events after dispatch is complete

Change-Id: I6f0c64d21d57512c5b329b561ccd415a93790dec
Signed-off-by: Sylvain Munaut <[email protected]>
---
M include/osmocom/core/fsm.h
M src/fsm.c
2 files changed, 72 insertions(+), 13 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/83/12983/1

diff --git a/include/osmocom/core/fsm.h b/include/osmocom/core/fsm.h
index df7e348..c1144c6 100644
--- a/include/osmocom/core/fsm.h
+++ b/include/osmocom/core/fsm.h
@@ -17,6 +17,9 @@

 struct osmo_fsm_inst;

+/*! Maximum number of pending events to be disptached to an FSM instance */
+#define OSMO_FSM_MAX_PENDING_EVENTS 8
+
 enum osmo_fsm_term_cause {
        /*! terminate because parent terminated */
        OSMO_FSM_TERM_PARENT,
@@ -115,6 +118,20 @@
                /*! \ref llist_head linked to parent->proc.children */
                struct llist_head child;
        } proc;
+
+       /*! Busy inside dispatch */
+       int in_dispatch;
+
+       /*! Queue of events to dispatch */
+       struct {
+               uint32_t event;
+               void *data;
+               const char *src_file;
+               int src_line;
+       } evt_queue[OSMO_FSM_MAX_PENDING_EVENTS];
+
+       /*! Number of events queued */
+       int evt_queue_len;
 };

 void osmo_fsm_log_addr(bool log_addr);
diff --git a/src/fsm.c b/src/fsm.c
index 6e15ab7..46128d3 100644
--- a/src/fsm.c
+++ b/src/fsm.c
@@ -571,6 +571,7 @@
 {
        struct osmo_fsm *fsm;
        const struct osmo_fsm_state *fs;
+       int i;

        if (!fi) {
                LOGPSRC(DLGLOBAL, LOGL_ERROR, file, line,
@@ -581,26 +582,67 @@
        }

        fsm = fi->fsm;
-       OSMO_ASSERT(fi->state < fsm->num_states);
-       fs = &fi->fsm->states[fi->state];

-       LOGPFSMSRC(fi, file, line,
-                  "Received Event %s\n", osmo_fsm_event_name(fsm, event));
+//     LOGPFSMSRC(fi, file, line,
+//                "Received Event %s%s.\n",
+//                osmo_fsm_event_name(fsm, event),
+//                fi->in_dispatch ? " while in dispatch, queing it" : "");

-       if (((1 << event) & fsm->allstate_event_mask) && fsm->allstate_action) {
-               fsm->allstate_action(fi, event, data);
+       if (fi->evt_queue_len == OSMO_FSM_MAX_PENDING_EVENTS) {
+               LOGPFSMSRC(fi, file, line,
+                          "Unable to queue event %s, overflow ...\n",
+                          osmo_fsm_event_name(fsm, event));
+
+               return -ENOMEM;
+       }
+
+       fi->evt_queue[fi->evt_queue_len].event = event;
+       fi->evt_queue[fi->evt_queue_len].data = data;
+       fi->evt_queue[fi->evt_queue_len].src_file = file;
+       fi->evt_queue[fi->evt_queue_len].src_line = line;
+       fi->evt_queue_len++;
+
+       if (fi->in_dispatch) {
+               LOGPFSMSRC(fi, file, line,
+                          "Deferred Event %s\n",
+                          osmo_fsm_event_name(fsm, event));
                return 0;
        }

-       if (!((1 << event) & fs->in_event_mask)) {
-               LOGPFSMLSRC(fi, LOGL_ERROR, file, line,
-                           "Event %s not permitted\n",
-                           osmo_fsm_event_name(fsm, event));
-               return -1;
+       fi->in_dispatch = 1;
+
+       for (i=0; i < fi->evt_queue_len; i++) {
+               OSMO_ASSERT(fi->state < fsm->num_states);
+               fs = &fi->fsm->states[fi->state];
+
+               event = fi->evt_queue[i].event;
+               data  = fi->evt_queue[i].data;
+               file  = fi->evt_queue[i].src_file;
+               line  = fi->evt_queue[i].src_line;
+
+//             LOGPFSMSRC(fi, file, line,
+//                        "Processing Event %s\n", osmo_fsm_event_name(fsm, 
event));
+               LOGPFSMSRC(fi, file, line,
+                          "Received Event %s\n", osmo_fsm_event_name(fsm, 
event));
+
+               if (((1 << event) & fsm->allstate_event_mask) && 
fsm->allstate_action) {
+                       fsm->allstate_action(fi, event, data);
+                       continue;
+               }
+
+               if (!((1 << event) & fs->in_event_mask)) {
+                       LOGPFSMLSRC(fi, LOGL_ERROR, file, line,
+                                   "Event %s not permitted\n",
+                                   osmo_fsm_event_name(fsm, event));
+                       continue;
+               }
+
+               if (fs->action)
+                       fs->action(fi, event, data);
        }

-       if (fs->action)
-               fs->action(fi, event, data);
+       fi->evt_queue_len = 0;
+       fi->in_dispatch = 0;

        return 0;
 }

--
To view, visit https://gerrit.osmocom.org/12983
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6f0c64d21d57512c5b329b561ccd415a93790dec
Gerrit-Change-Number: 12983
Gerrit-PatchSet: 1
Gerrit-Owner: tnt <[email protected]>

Reply via email to