Browse Source

Merge branch 'master' into typedescription

Conflicts:
	CMakeLists.txt
	src/server/ua_server.c
Julius Pfrommer 9 years ago
parent
commit
4dacc66378

+ 4 - 0
CMakeLists.txt

@@ -91,6 +91,8 @@ endif()
 
 add_library(open62541-objects OBJECT ${lib_sources}) # static version that exports all symbols
 add_library(open62541 SHARED $<TARGET_OBJECTS:open62541-objects>)
+add_library(open62541-static STATIC $<TARGET_OBJECTS:open62541-objects>)
+SET_TARGET_PROPERTIES(open62541-static PROPERTIES OUTPUT_NAME open62541 CLEAN_DIRECT_OUTPUT 1) # static version that exports all symbols
 target_compile_definitions(open62541-objects PUBLIC UA_DYNAMIC_LINKING)
 
 ## logging
@@ -160,6 +162,8 @@ add_executable(exampleServer ${server_sources} ${exported_headers} ${generated_h
 target_link_libraries(exampleServer open62541)
 if(WIN32)
     target_link_libraries(exampleServer ws2_32)
+else()
+    target_link_libraries(exampleServer rt)
 endif(WIN32)
 if(MULTITHREADING)
     target_link_libraries(exampleServer urcu-cds urcu urcu-common pthread)

+ 2 - 2
include/ua_server.h

@@ -96,7 +96,7 @@ typedef struct UA_WorkItem {
  * @param work Pointer to the WorkItem that shall be added. The pointer is not
  *        freed but copied to an internal representation.
  *
- * @param time The time when the work shall be executed. If the time lies in the
+ * @param executionTime The time when the work shall be executed. If the time lies in the
  *        past, the work will be executed in the next iteration of the server's
  *        main loop
  *
@@ -107,7 +107,7 @@ typedef struct UA_WorkItem {
  * @return Upon sucess, UA_STATUSCODE_GOOD is returned. An error code otherwise.
  */
 UA_StatusCode UA_EXPORT UA_Server_addTimedWorkItem(UA_Server *server, const UA_WorkItem *work,
-                                                   UA_DateTime time, UA_Guid *resultWorkGuid);
+                                                   UA_DateTime executionTime, UA_Guid *resultWorkGuid);
 
 /**
  * @param server The server object.

+ 4 - 3
ports/WAGO-750-860.patch

@@ -36,14 +36,15 @@ index c785182..9e66da0 100644
  	endif()
  endif()
  
-@@ -150,8 +147,8 @@ else()
+@@ -149,10 +149,7 @@ else()
  endif()
  
- add_library(open62541-objects OBJECT ${lib_sources}) # static version that exports all symbols
+ add_library(open62541-objects OBJECT ${lib_sources}) 
 -add_library(open62541 SHARED $<TARGET_OBJECTS:open62541-objects>)
+-add_library(open62541-static STATIC $<TARGET_OBJECTS:open62541-objects>)
+-SET_TARGET_PROPERTIES(open62541-static PROPERTIES OUTPUT_NAME open62541 CLEAN_DIRECT_OUTPUT 1) # static version that exports all symbols
 -target_compile_definitions(open62541-objects PUBLIC UA_DYNAMIC_LINKING)
 +add_library(open62541 $<TARGET_OBJECTS:open62541-objects>)
-+#target_compile_definitions(open62541-objects PUBLIC UA_DYNAMIC_LINKING)
  
  ## logging
  set(UA_LOGLEVEL 400 CACHE STRING "Level at which logs shall be reported")

+ 2 - 1
src/server/ua_server.c

@@ -63,10 +63,11 @@ void UA_Server_delete(UA_Server *server) {
     UA_ByteString_deleteMembers(&server->serverCertificate);
     UA_Array_delete(server->endpointDescriptions, server->endpointDescriptionsSize,
                     &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
-    UA_free(server);
 #ifdef UA_MULTITHREADING
+    pthread_cond_destroy(&server->dispatchQueue_condition); // so the workers don't spin if the queue is empty
     rcu_barrier(); // wait for all scheduled call_rcu work to complete
 #endif
+    UA_free(server);
 }
 
 UA_Server * UA_Server_new(void) {

+ 1 - 0
src/server/ua_server_internal.h

@@ -57,6 +57,7 @@ struct UA_Server {
     // worker threads wait on the queue
 	struct cds_wfcq_head dispatchQueue_head;
 	struct cds_wfcq_tail dispatchQueue_tail;
+    pthread_cond_t dispatchQueue_condition; // so the workers don't spin if the queue is empty
 #endif
 
     LIST_HEAD(UA_TimedWorkList, UA_TimedWork) timedWork;

+ 22 - 4
src/server/ua_server_worker.c

@@ -1,4 +1,9 @@
 #include <stdio.h>
+#define __USE_POSIX
+#define _XOPEN_SOURCE 500
+#define __USE_POSIX199309
+#include <sys/time.h>
+#include <time.h>
 #include "ua_server_internal.h"
 
 /**
@@ -14,7 +19,7 @@
  *    all previous work has actually finished (only for multithreading)
  */
 
-#define MAXTIMEOUT 5000 // max timeout in usec until the next main loop iteration
+#define MAXTIMEOUT 50000 // max timeout in usec until the next main loop iteration
 #define BATCHSIZE 20 // max size of worklists that are dispatched to workers
 
 static void processWork(UA_Server *server, const UA_WorkItem *work, UA_Int32 workSize) {
@@ -93,6 +98,11 @@ static void * workerLoop(struct workerStartData *startInfo) {
     UA_Server *server = startInfo->server;
     UA_free(startInfo);
     
+    pthread_mutex_t mutex; // required for the condition variable
+    pthread_mutex_init(&mutex,0);
+    pthread_mutex_lock(&mutex);
+    struct timespec to;
+
     while(*server->running) {
         struct workListNode *wln = (struct workListNode*)
             cds_wfcq_dequeue_blocking(&server->dispatchQueue_head, &server->dispatchQueue_tail);
@@ -100,9 +110,15 @@ static void * workerLoop(struct workerStartData *startInfo) {
             processWork(server, wln->work, wln->workSize);
             UA_free(wln->work);
             UA_free(wln);
+        } else {
+            clock_gettime(CLOCK_REALTIME, &to);
+            to.tv_sec += 2;
+            pthread_cond_timedwait(&server->dispatchQueue_condition, &mutex, &to);
         }
         uatomic_inc(c); // increase the workerCounter;
     }
+    pthread_mutex_unlock(&mutex);
+    pthread_mutex_destroy(&mutex);
    	rcu_unregister_thread();
     return UA_NULL;
 }
@@ -184,9 +200,9 @@ static UA_StatusCode addTimedWork(UA_Server *server, const UA_WorkItem *item, UA
 }
 
 // Currently, these functions need to get the server mutex, but should be sufficiently fast
-UA_StatusCode UA_Server_addTimedWorkItem(UA_Server *server, const UA_WorkItem *work, UA_DateTime time,
+UA_StatusCode UA_Server_addTimedWorkItem(UA_Server *server, const UA_WorkItem *work, UA_DateTime executionTime,
                                          UA_Guid *resultWorkGuid) {
-    return addTimedWork(server, work, time, 0, resultWorkGuid);
+    return addTimedWork(server, work, executionTime, 0, resultWorkGuid);
 }
 
 UA_StatusCode UA_Server_addRepeatedWorkItem(UA_Server *server, const UA_WorkItem *work, UA_UInt32 interval,
@@ -392,6 +408,7 @@ UA_StatusCode UA_Server_run(UA_Server *server, UA_UInt16 nThreads, UA_Boolean *r
     // 1) Prepare the threads
     server->running = running; // the threads need to access the variable
     server->nThreads = nThreads;
+    pthread_cond_init(&server->dispatchQueue_condition, 0);
     pthread_t *thr = UA_malloc(nThreads * sizeof(pthread_t));
     server->workerCounters = UA_malloc(nThreads * sizeof(UA_UInt32 *));
     for(UA_UInt32 i=0;i<nThreads;i++) {
@@ -439,13 +456,14 @@ UA_StatusCode UA_Server_run(UA_Server *server, UA_UInt16 nThreads, UA_Boolean *r
                 work[k].type = UA_WORKITEMTYPE_NOTHING;
             }
             dispatchWork(server, workSize, work);
+            if(workSize > 0)
+                pthread_cond_broadcast(&server->dispatchQueue_condition); 
 #else
             processWork(server, work, workSize);
             UA_free(work);
 #endif
         }
 
-
         // 3.3) Exit?
         if(!*running)
             break;