beremiz

Parents 65f32c94d7ec
Children 7825a76f5ffb
SVGHMI: Send thread now is a thread created in svghmi.c (was a python thread). Still works on vanilla linux, still not on bugous xenomai 3.1rc3 posix skin
--- 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 <pthread.h>
#include <errno.h>
+#include <pthread.h>
#include "iec_types_all.h"
#include "POUS.h"
#include "config.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)
+{
+ while(1){
+ int do_collect;
+ int ret = pthread_mutex_lock(&svghmi_send_WakeCondLock);
+ if(continue_collect) {
+ ret = pthread_cond_wait(&svghmi_send_WakeCond, &svghmi_send_WakeCondLock);
+ do_collect = continue_collect; // continue_collect might have changed
+ }else{
+ do_collect = 0;
+ }
+
+
+ pthread_mutex_unlock(&svghmi_send_WakeCondLock);
+
+ if(do_collect) {
+ pthread_mutex_lock(&svghmi_send_collect_callback_lock);
+ if(svghmi_send_collect_callback) {
+ int res;
+ 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);
+ char *ptr = &sbuf[0];
+ uint32_t size = sbufidx;
+ svghmi_send_collect_callback(size, ptr);
+ }
+ }
+ }
+ pthread_mutex_unlock(&svghmi_send_collect_callback_lock);
+ }
+ else
+ {
+ return;
+ }
+ }
+}
+
int __init_svghmi()
{
bzero(rbuf,sizeof(rbuf));
bzero(wbuf,sizeof(wbuf));
continue_collect = 1;
+ int res = pthread_create(&svghmi_send_collect_thread,
+ NULL,
+ (void*) &svghmi_send_collect_thread_proc,
+ NULL);
+
return 0;
}
void __cleanup_svghmi()
{
+
pthread_mutex_lock(&svghmi_send_WakeCondLock);
continue_collect = 0;
pthread_cond_signal(&svghmi_send_WakeCond);
pthread_mutex_unlock(&svghmi_send_WakeCondLock);
+
+ pthread_join(svghmi_send_collect_thread, NULL);
}
void __retrieve_svghmi()
@@ -226,38 +279,12 @@
}
/* PYTHON CALLS */
-int svghmi_send_collect(uint32_t *size, char **ptr){
- int do_collect;
- pthread_mutex_lock(&svghmi_send_WakeCondLock);
- do_collect = continue_collect;
- if(do_collect)
- {
- pthread_cond_wait(&svghmi_send_WakeCond, &svghmi_send_WakeCondLock);
- do_collect = continue_collect;
- }
- pthread_mutex_unlock(&svghmi_send_WakeCondLock);
-
- if(do_collect) {
- int res;
- 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);
- *ptr = &sbuf[0];
- *size = sbufidx;
- return 0;
- }
- return ENODATA;
- }
- // printf("collected BAD result %%d\n", res);
- return res;
- }
- else
- {
- return EINTR;
- }
+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);
}
typedef enum {
--- 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_session = None
-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_root = None
svghmi_listener = None
-svghmi_send_thread = None
-def SendThreadProc():
- global svghmi_session
- size = ctypes.c_uint32()
- ptr = ctypes.c_void_p()
- res = 0
- while True:
- res=svghmi_send_collect(ctypes.byref(size), ctypes.byref(ptr))
- if res == 0:
- # 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]:
- break
-
-
+def send_collect_callback(size, ptr):
+ # TODO multiclient : dispatch to sessions
+ if svghmi_session is not None:
+ print(size, ptr)
+ return svghmi_session.sendMessage(ctypes.string_at(ptr,size))
+ return 0
# Called by PLCObject at start
def _runtime_svghmi0_start():
- global svghmi_listener, svghmi_root, svghmi_send_thread
+ global svghmi_listener, svghmi_root
svghmi_root = Resource()
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_session.close()
svghmi_root.delEntity("ws")
@@ -135,6 +122,4 @@
svghmi_listener.stopListening()
svghmi_listener = None
# plc cleanup calls svghmi_(locstring)_cleanup and unlocks send thread
- svghmi_send_thread.join()
- svghmi_send_thread = None