SVGHMI: finished multiclient support. Still needs more testing.
--- a/svghmi/svghmi.c Mon Jul 12 10:07:52 2021 +0200
+++ b/svghmi/svghmi.c Mon Jul 12 14:13:29 2021 +0200
@@ -84,49 +84,51 @@
static int write_iterator(uint32_t index, hmi_tree_item_t *dsc)
{
uint32_t session_index = 0;
- if(AtomicCompareExchange(&dsc->wlock, 0, 1) == 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;
- }
- }
- }
-
+ int value_changed = 0;
+ if(AtomicCompareExchange(&dsc->wlock, 0, 1) == 0) {
void *dest_p = &wbuf[dsc->buf_index];
void *real_value_p = NULL;
char flags = 0;
void *visible_value_p = UnpackVar(dsc, &real_value_p, &flags);
-
- /* if new value differs from previous one */
USINT sz = __get_type_enum_size(dsc->type);
if(__Is_a_string(dsc)){
sz = ((STRING*)visible_value_p)->len + 1;
}
- if(dsc->wstate[session_index] == buf_new /* just subscribed
- or already subscribed having value change */
- || (dsc->refresh_period_ms[session_index] > 0 && memcmp(dest_p, visible_value_p, sz) != 0)){
- /* copy and flag as set */
+ 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;
+ }
+ }
+ }
+
+ if(dsc->wstate[session_index] == buf_new /* just subscribed
+ or already subscribed having value change */
+ || (dsc->refresh_period_ms[session_index] > 0
+ && (value_changed || (value_changed=memcmp(dest_p, visible_value_p, sz))) != 0)){
+ /* if not already marked/signaled, do it */
+ 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, visible_value_p, sz);
- /* if not already marked/signaled, do it */
- 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;
- }
- }
-
AtomicCompareExchange(&dsc->wlock, 1, 0);
- session_index++;
}
// else ... : PLC can't wait, variable will be updated next turn
return 0;
--- a/svghmi/svghmi_server.py Mon Jul 12 10:07:52 2021 +0200
+++ b/svghmi/svghmi_server.py Mon Jul 12 14:13:29 2021 +0200
@@ -103,11 +103,11 @@
self.free_index(session.session_index)
self.session_count -= 1
session.kill()
-
+
def close_all(self):
for session in self.iter_sessions():
self.unregister(session)
-
+
def iter_sessions(self):
with self.lock:
lst = list(self.multiclient_sessions)
@@ -247,8 +247,6 @@
while not(finished):
svghmi_wait()
for svghmi_session in svghmi_session_manager.iter_sessions():
- # TODO make svghmi_send_collect waiting only once per
- # svghmi_session_manager.iter_sessions cycle
res = svghmi_send_collect(
svghmi_session.session_index,
ctypes.byref(size), ctypes.byref(ptr))