--- a/svghmi/svghmi.c Tue Dec 03 09:46:12 2019 +0100
+++ b/svghmi/svghmi.c Fri Dec 06 11:45:03 2019 +0100
@@ -1,5 +1,6 @@
#include "iec_types_all.h"
@@ -191,24 +192,76 @@
static pthread_cond_t svghmi_send_WakeCond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t svghmi_send_WakeCondLock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t svghmi_send_collect_callback_lock = PTHREAD_MUTEX_INITIALIZER; +pthread_t svghmi_send_collect_thread; +typedef int (*svghmi_send_collect_callback_t)(uint32_t size, char *ptr); +static svghmi_send_collect_callback_t svghmi_send_collect_callback; static int continue_collect;
+void svghmi_send_collect_thread_proc(void *args) + int ret = pthread_mutex_lock(&svghmi_send_WakeCondLock); + ret = pthread_cond_wait(&svghmi_send_WakeCond, &svghmi_send_WakeCondLock); + do_collect = continue_collect; // continue_collect might have changed + pthread_mutex_unlock(&svghmi_send_WakeCondLock); + pthread_mutex_lock(&svghmi_send_collect_callback_lock); + if(svghmi_send_collect_callback) { + sbufidx = HMI_HASH_SIZE; + if((res = traverse_hmi_tree(send_iterator)) == 0) + if(sbufidx > HMI_HASH_SIZE){ + memcpy(&sbuf[0], &hmi_hash[0], HMI_HASH_SIZE); + uint32_t size = sbufidx; + svghmi_send_collect_callback(size, ptr); + pthread_mutex_unlock(&svghmi_send_collect_callback_lock); bzero(rbuf,sizeof(rbuf));
bzero(wbuf,sizeof(wbuf));
+ int res = pthread_create(&svghmi_send_collect_thread, + (void*) &svghmi_send_collect_thread_proc, pthread_mutex_lock(&svghmi_send_WakeCondLock);
pthread_cond_signal(&svghmi_send_WakeCond);
pthread_mutex_unlock(&svghmi_send_WakeCondLock);
+ pthread_join(svghmi_send_collect_thread, NULL); @@ -226,38 +279,12 @@
-int svghmi_send_collect(uint32_t *size, char **ptr){
- pthread_mutex_lock(&svghmi_send_WakeCondLock);
- do_collect = continue_collect;
- pthread_cond_wait(&svghmi_send_WakeCond, &svghmi_send_WakeCondLock);
- do_collect = continue_collect;
- pthread_mutex_unlock(&svghmi_send_WakeCondLock);
- sbufidx = HMI_HASH_SIZE;
- if((res = traverse_hmi_tree(send_iterator)) == 0)
- if(sbufidx > HMI_HASH_SIZE){
- memcpy(&sbuf[0], &hmi_hash[0], HMI_HASH_SIZE);
- // printf("collected BAD result %%d\n", res);
+void svghmi_register_send_collect_callback(svghmi_send_collect_callback_t callback) + pthread_mutex_lock(&svghmi_send_collect_callback_lock); + svghmi_send_collect_callback = callback; + pthread_mutex_unlock(&svghmi_send_collect_callback_lock); --- a/svghmi/svghmi_server.py Tue Dec 03 09:46:12 2019 +0100
+++ b/svghmi/svghmi_server.py Fri Dec 06 11:45:03 2019 +0100
@@ -23,12 +23,10 @@
-svghmi_send_collect = PLCBinary.svghmi_send_collect
-svghmi_send_collect.restype = ctypes.c_int # error or 0
-svghmi_send_collect.argtypes = [
- ctypes.POINTER(ctypes.c_uint32), # size
- ctypes.POINTER(ctypes.c_void_p)] # data ptr
-# TODO multiclient : switch to arrays
+svghmi_send_collect_callback_t = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_uint32, ctypes.c_void_p) +svghmi_register_send_collect_callback = PLCBinary.svghmi_register_send_collect_callback +svghmi_register_send_collect_callback.restype = ctypes.c_int # error or 0 +svghmi_register_send_collect_callback.argtypes = [svghmi_send_collect_callback_t] svghmi_recv_dispatch = PLCBinary.svghmi_recv_dispatch
svghmi_recv_dispatch.restype = ctypes.c_int # error or 0
@@ -92,42 +90,31 @@
-svghmi_send_thread = None
- size = ctypes.c_uint32()
- ptr = ctypes.c_void_p()
- res=svghmi_send_collect(ctypes.byref(size), ctypes.byref(ptr))
- # TODO multiclient : dispatch to sessions
- if svghmi_session is not None:
- svghmi_session.sendMessage(ctypes.string_at(ptr.value,size.value))
- elif res not in [errno.EAGAIN, errno.ENODATA]:
+def send_collect_callback(size, ptr): + # TODO multiclient : dispatch to sessions + if svghmi_session is not None: + return svghmi_session.sendMessage(ctypes.string_at(ptr,size)) # Called by PLCObject at start
def _runtime_svghmi0_start():
- global svghmi_listener, svghmi_root, svghmi_send_thread
+ global svghmi_listener, svghmi_root svghmi_root.putChild("ws", WebSocketResource(HMIWebSocketServerFactory()))
svghmi_listener = reactor.listenTCP(8008, Site(svghmi_root))
- # start a thread that call the C part of SVGHMI
- svghmi_send_thread = Thread(target=SendThreadProc, name="SVGHMI Send")
- svghmi_send_thread.start()
+ # # start a thread that call the C part of SVGHMI + svghmi_register_send_collect_callback(svghmi_send_collect_callback_t(send_collect_callback)) # Called by PLCObject at stop
def _runtime_svghmi0_stop():
- global svghmi_listener, svghmi_root, svghmi_send_thread, svghmi_session
+ global svghmi_listener, svghmi_root, svghmi_session if svghmi_session is not None:
svghmi_root.delEntity("ws")
@@ -135,6 +122,4 @@
svghmi_listener.stopListening()
# plc cleanup calls svghmi_(locstring)_cleanup and unlocks send thread
- svghmi_send_thread.join()
- svghmi_send_thread = None