Fix bug introduced in previous commit : dual link list wasn't append and remove wasn't implemented correctly. Removed debug code, enhanced variable names and comments. RuntimeLists
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Mon, 27 Dec 2021 19:21:59 +0100
branchRuntimeLists
changeset 3400 c2b46d0965ca
parent 3399 95e0b926a8c3
child 3401 526785cdc97a
Fix bug introduced in previous commit : dual link list wasn't append and remove wasn't implemented correctly. Removed debug code, enhanced variable names and comments.
svghmi/svghmi.c
--- a/svghmi/svghmi.c	Thu Dec 23 11:36:37 2021 +0100
+++ b/svghmi/svghmi.c	Mon Dec 27 19:21:59 2021 +0100
@@ -98,71 +98,68 @@
 
 static int write_iterator(hmi_tree_item_t *dsc)
 {
-    {
-        uint32_t session_index = 0;
-        int value_changed = 0;
-        void *dest_p = NULL;
-        void *value_p = NULL;
-        size_t sz = 0;
-        while(session_index < MAX_CONNECTIONS) {
-            if(dsc->wstate[session_index] == buf_set){
-                /* if being subscribed */
-                if(dsc->refresh_period_ms[session_index]){
-                    if(dsc->age_ms[session_index] + ticktime_ms < dsc->refresh_period_ms[session_index]){
-                        dsc->age_ms[session_index] += ticktime_ms;
-                    }else{
-                        dsc->wstate[session_index] = buf_tosend;
-                        global_write_dirty = 1;
-                    }
-                }
-            }
-
-            /* variable is sample only if just subscribed
-               or already subscribed and having value change */
-            int do_sample = 0;
-            int just_subscribed = dsc->wstate[session_index] == buf_new;
-            if(!just_subscribed){
-                int already_subscribed = dsc->refresh_period_ms[session_index] > 0;
-                if(already_subscribed){
-                    if(!value_changed){
-                        if(!value_p){
-                            UnpackVar(dsc, &value_p, NULL, &sz);
-                            if(__Is_a_string(dsc)){
-                                sz = ((STRING*)value_p)->len + 1;
-                            }
-                            dest_p = &wbuf[dsc->buf_index];
+    uint32_t session_index = 0;
+    int value_changed = 0;
+    void *dest_p = NULL;
+    void *value_p = NULL;
+    size_t sz = 0;
+    while(session_index < MAX_CONNECTIONS) {
+        if(dsc->wstate[session_index] == buf_set){
+            /* if being subscribed */
+            if(dsc->refresh_period_ms[session_index]){
+                if(dsc->age_ms[session_index] + ticktime_ms < dsc->refresh_period_ms[session_index]){
+                    dsc->age_ms[session_index] += ticktime_ms;
+                }else{
+                    dsc->wstate[session_index] = buf_tosend;
+                    global_write_dirty = 1;
+                }
+            }
+        }
+
+        /* variable is sample only if just subscribed
+           or already subscribed and having value change */
+        int do_sample = 0;
+        int just_subscribed = dsc->wstate[session_index] == buf_new;
+        if(!just_subscribed){
+            int already_subscribed = dsc->refresh_period_ms[session_index] > 0;
+            if(already_subscribed){
+                if(!value_changed){
+                    if(!value_p){
+                        UnpackVar(dsc, &value_p, NULL, &sz);
+                        if(__Is_a_string(dsc)){
+                            sz = ((STRING*)value_p)->len + 1;
                         }
-                        value_changed = memcmp(dest_p, value_p, sz) != 0;
-                        do_sample = value_changed;
-                    }else{
-                        do_sample = 1;
-                    }
-                }
-            } else {
-                do_sample = 1;
-            }
-
-
-            if(do_sample){
-                if(dsc->wstate[session_index] != buf_set && dsc->wstate[session_index] != buf_tosend) {
-                    if(dsc->wstate[session_index] == buf_new \
-                       || ticktime_ms > dsc->refresh_period_ms[session_index]){
-                        dsc->wstate[session_index] = buf_tosend;
-                        global_write_dirty = 1;
-                    } else {
-                        dsc->wstate[session_index] = buf_set;
-                    }
-                    dsc->age_ms[session_index] = 0;
-                }
-            }
-
-            session_index++;
-        }
-        /* copy value if changed (and subscribed) */
-        if(value_changed)
-            memcpy(dest_p, value_p, sz);
-    }
-    // else ... : PLC can't wait, variable will be updated next turn
+                        dest_p = &wbuf[dsc->buf_index];
+                    }
+                    value_changed = memcmp(dest_p, value_p, sz) != 0;
+                    do_sample = value_changed;
+                }else{
+                    do_sample = 1;
+                }
+            }
+        } else {
+            do_sample = 1;
+        }
+
+
+        if(do_sample){
+            if(dsc->wstate[session_index] != buf_set && dsc->wstate[session_index] != buf_tosend) {
+                if(dsc->wstate[session_index] == buf_new \
+                   || ticktime_ms > dsc->refresh_period_ms[session_index]){
+                    dsc->wstate[session_index] = buf_tosend;
+                    global_write_dirty = 1;
+                } else {
+                    dsc->wstate[session_index] = buf_set;
+                }
+                dsc->age_ms[session_index] = 0;
+            }
+        }
+
+        session_index++;
+    }
+    /* copy value if changed (and subscribed) */
+    if(value_changed)
+        memcpy(dest_p, value_p, sz);
     return 0;
 }
 
@@ -213,34 +210,31 @@
     uint32_t other_session_index = 0;
     int previously_subscribed = 0;
     int session_only_subscriber = 0;
-    int session_subscriber = 0;
+    int session_already_subscriber = 0;
     int needs_subscription_for_session = (refresh_period_ms != 0);
 
     while(other_session_index < session_index) {
         previously_subscribed |= (dsc->refresh_period_ms[other_session_index++] != 0);
     }
-    session_subscriber = (dsc->refresh_period_ms[other_session_index++] != 0);
+    session_already_subscriber = (dsc->refresh_period_ms[other_session_index++] != 0);
     while(other_session_index < MAX_CONNECTIONS) {
         previously_subscribed |= (dsc->refresh_period_ms[other_session_index++] != 0);
     }
-    session_only_subscriber = session_subscriber && !previously_subscribed;
-    previously_subscribed |= session_subscriber;
-
-    printf("update_refresh_period %%x,%%x index:%%d session_index:%%d refresh_period_ms:%%d\n",
-           dsc,
-           hmi_tree_items,
-           dsc - hmi_tree_items,
-           session_index,
-           refresh_period_ms);
+    session_only_subscriber = session_already_subscriber && !previously_subscribed;
+    previously_subscribed |= session_already_subscriber;
 
     if(needs_subscription_for_session) {
-        if(!session_subscriber)
+        if(!session_already_subscriber)
         {
             dsc->wstate[session_index] = buf_new;
         }
-        /* if not already subscribed */
+        /* item is appended to list only when no session was previously subscribed */
         if(!previously_subscribed){
             /* append subsciption to list */
+            if(subscriptions_tail != NULL){ 
+                /* if list wasn't empty, link with previous tail*/
+                subscriptions_tail->subscriptions_next = dsc;
+            }
             dsc->subscriptions_prev = subscriptions_tail;
             subscriptions_tail = dsc;
             dsc->subscriptions_next = NULL;
@@ -252,8 +246,13 @@
             if(dsc->subscriptions_next == NULL){ /* remove tail  */
                 /* re-link tail to previous */
                 subscriptions_tail = dsc->subscriptions_prev;
+                if(subscriptions_tail != NULL){
+                    subscriptions_tail->subscriptions_next = NULL;
+                }
+            } else if(dsc->subscriptions_prev == NULL){ /* remove head  */
+                dsc->subscriptions_next->subscriptions_prev = NULL;
             } else { /* remove entry in between other entries */
-                /* re-link previous iand next node */
+                /* re-link previous and next node */
                 dsc->subscriptions_next->subscriptions_prev = dsc->subscriptions_prev;
                 dsc->subscriptions_prev->subscriptions_next = dsc->subscriptions_next;
             }
@@ -309,11 +308,12 @@
         hmi_tree_item_t *dsc = incoming_tail;
         /* iterate through read list (changes from HMI) */
         while(dsc){
+            hmi_tree_item_t *_dsc = dsc->incoming_prev;
             read_iterator(dsc);
-            dsc = dsc->incoming_prev;
             /* unnecessary
             dsc->incoming_prev = NULL;
             */
+            dsc = _dsc;
         }
         /* flush read list */
         incoming_tail = NULL;
@@ -347,6 +347,7 @@
 
 int svghmi_send_collect(uint32_t session_index, uint32_t *size, char **ptr){
 
+
     if(svghmi_continue_collect) {
         int res;
         sbufidx = HMI_HASH_SIZE;
@@ -358,7 +359,6 @@
         hmi_tree_item_t *dsc = subscriptions_tail;
         while(dsc){
             uint32_t index = dsc - hmi_tree_items;
-            printf("Send index %%d\n", index);
             res = send_iterator(index, dsc, session_index);
             if(res != 0){
                 break;
@@ -377,7 +377,6 @@
             AtomicCompareExchange(&hmitree_wlock, 1, 0);
             return ENODATA;
         }
-        // printf("collected BAD result %%d\n", res);
         AtomicCompareExchange(&hmitree_wlock, 1, 0);
         return res;
     }
@@ -396,10 +395,15 @@
 
 int svghmi_reset(uint32_t session_index){
     hmi_tree_item_t *dsc = subscriptions_tail;
+    while(AtomicCompareExchange(&hmitree_wlock, 0, 1)){
+        nRT_reschedule();
+    }
     while(dsc){
+        hmi_tree_item_t *_dsc = dsc->subscriptions_prev;
         update_refresh_period(dsc, session_index, 0);
-        dsc = dsc->subscriptions_prev;
-    }
+        dsc = _dsc;
+    }
+    AtomicCompareExchange(&hmitree_wlock, 1, 0);
     return 1;
 }
 
@@ -431,6 +435,7 @@
         cmd_old = cmd;
         cmd = *(cursor++);
 
+
         if(cmd_old != cmd){
             if(got_wlock){
                 AtomicCompareExchange(&hmitree_wlock, 1, 0);
@@ -448,6 +453,7 @@
                 uint32_t index = *(uint32_t*)(cursor);
                 uint8_t const *valptr = cursor + sizeof(uint32_t);
 
+
                 if(index == heartbeat_index)
                     was_hearbeat = 1;
 
@@ -511,8 +517,9 @@
                 {
                     hmi_tree_item_t *dsc = subscriptions_tail;
                     while(dsc){
+                        hmi_tree_item_t *_dsc = dsc->subscriptions_prev;
                         update_refresh_period(dsc, session_index, 0);
-                        dsc = dsc->subscriptions_prev;
+                        dsc = _dsc;
                     }
                 }
             }