|
@@ -44,15 +44,16 @@ struct UA_Worker {
|
|
|
sizeof(UA_UInt32) - sizeof(UA_Boolean)];
|
|
|
};
|
|
|
|
|
|
-typedef struct {
|
|
|
- struct cds_wfcq_node node;
|
|
|
+struct UA_WorkerCallback {
|
|
|
+ SIMPLEQ_ENTRY(UA_WorkerCallback) next;
|
|
|
UA_ServerCallback callback;
|
|
|
void *data;
|
|
|
|
|
|
UA_Boolean delayed;
|
|
|
UA_Boolean countersSampled;
|
|
|
UA_UInt32 workerCounters[];
|
|
|
-} WorkerCallback;
|
|
|
+};
|
|
|
+typedef struct UA_WorkerCallback WorkerCallback;
|
|
|
|
|
|
|
|
|
static void
|
|
@@ -69,16 +70,19 @@ workerLoop(UA_Worker *worker) {
|
|
|
UA_random_seed((uintptr_t)worker);
|
|
|
|
|
|
while(*running) {
|
|
|
- UA_atomic_add(counter, 1);
|
|
|
- WorkerCallback *dc = (WorkerCallback*)
|
|
|
- cds_wfcq_dequeue_blocking(&server->dispatchQueue_head,
|
|
|
- &server->dispatchQueue_tail);
|
|
|
+ UA_atomic_addUInt32(counter, 1);
|
|
|
+ pthread_mutex_lock(&server->dispatchQueue_accessMutex);
|
|
|
+ WorkerCallback *dc = SIMPLEQ_FIRST(&server->dispatchQueue);
|
|
|
+ if(dc) {
|
|
|
+ SIMPLEQ_REMOVE_HEAD(&server->dispatchQueue, next);
|
|
|
+ }
|
|
|
+ pthread_mutex_unlock(&server->dispatchQueue_accessMutex);
|
|
|
if(!dc) {
|
|
|
|
|
|
- pthread_mutex_lock(&server->dispatchQueue_mutex);
|
|
|
+ pthread_mutex_lock(&server->dispatchQueue_conditionMutex);
|
|
|
pthread_cond_wait(&server->dispatchQueue_condition,
|
|
|
- &server->dispatchQueue_mutex);
|
|
|
- pthread_mutex_unlock(&server->dispatchQueue_mutex);
|
|
|
+ &server->dispatchQueue_conditionMutex);
|
|
|
+ pthread_mutex_unlock(&server->dispatchQueue_conditionMutex);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
@@ -98,14 +102,14 @@ workerLoop(UA_Worker *worker) {
|
|
|
|
|
|
static void
|
|
|
emptyDispatchQueue(UA_Server *server) {
|
|
|
- while(!cds_wfcq_empty(&server->dispatchQueue_head,
|
|
|
- &server->dispatchQueue_tail)) {
|
|
|
- WorkerCallback *dc = (WorkerCallback*)
|
|
|
- cds_wfcq_dequeue_blocking(&server->dispatchQueue_head,
|
|
|
- &server->dispatchQueue_tail);
|
|
|
+ pthread_mutex_lock(&server->dispatchQueue_accessMutex);
|
|
|
+ WorkerCallback *dc;
|
|
|
+ while((dc = SIMPLEQ_FIRST(&server->dispatchQueue)) != NULL) {
|
|
|
+ SIMPLEQ_REMOVE_HEAD(&server->dispatchQueue, next);
|
|
|
dc->callback(server, dc->data);
|
|
|
UA_free(dc);
|
|
|
}
|
|
|
+ pthread_mutex_unlock(&server->dispatchQueue_accessMutex);
|
|
|
}
|
|
|
|
|
|
#endif
|
|
@@ -135,9 +139,9 @@ UA_Server_workerCallback(UA_Server *server, UA_ServerCallback callback,
|
|
|
dc->callback = callback;
|
|
|
dc->data = data;
|
|
|
dc->delayed = false;
|
|
|
- cds_wfcq_node_init(&dc->node);
|
|
|
- cds_wfcq_enqueue(&server->dispatchQueue_head,
|
|
|
- &server->dispatchQueue_tail, &dc->node);
|
|
|
+ pthread_mutex_lock(&server->dispatchQueue_accessMutex);
|
|
|
+ SIMPLEQ_INSERT_TAIL(&server->dispatchQueue, dc, next);
|
|
|
+ pthread_mutex_unlock(&server->dispatchQueue_accessMutex);
|
|
|
|
|
|
|
|
|
pthread_cond_broadcast(&server->dispatchQueue_condition);
|
|
@@ -210,9 +214,9 @@ UA_Server_delayedCallback(UA_Server *server, UA_ServerCallback callback,
|
|
|
dc->data = data;
|
|
|
dc->delayed = true;
|
|
|
dc->countersSampled = false;
|
|
|
- cds_wfcq_node_init(&dc->node);
|
|
|
- cds_wfcq_enqueue(&server->dispatchQueue_head,
|
|
|
- &server->dispatchQueue_tail, &dc->node);
|
|
|
+ pthread_mutex_lock(&server->dispatchQueue_accessMutex);
|
|
|
+ SIMPLEQ_INSERT_TAIL(&server->dispatchQueue, dc, next);
|
|
|
+ pthread_mutex_unlock(&server->dispatchQueue_accessMutex);
|
|
|
|
|
|
|
|
|
pthread_cond_broadcast(&server->dispatchQueue_condition);
|
|
@@ -229,9 +233,9 @@ processDelayedCallback(UA_Server *server, WorkerCallback *dc) {
|
|
|
dc->countersSampled = true;
|
|
|
|
|
|
|
|
|
- cds_wfcq_node_init(&dc->node);
|
|
|
- cds_wfcq_enqueue(&server->dispatchQueue_head,
|
|
|
- &server->dispatchQueue_tail, &dc->node);
|
|
|
+ pthread_mutex_lock(&server->dispatchQueue_accessMutex);
|
|
|
+ SIMPLEQ_INSERT_TAIL(&server->dispatchQueue, dc, next);
|
|
|
+ pthread_mutex_unlock(&server->dispatchQueue_accessMutex);
|
|
|
|
|
|
|
|
|
pthread_cond_broadcast(&server->dispatchQueue_condition);
|
|
@@ -251,9 +255,9 @@ processDelayedCallback(UA_Server *server, WorkerCallback *dc) {
|
|
|
* TODO: What is the impact of this loop?
|
|
|
* Can we add a small delay here? */
|
|
|
if(!ready) {
|
|
|
- cds_wfcq_node_init(&dc->node);
|
|
|
- cds_wfcq_enqueue(&server->dispatchQueue_head,
|
|
|
- &server->dispatchQueue_tail, &dc->node);
|
|
|
+ pthread_mutex_lock(&server->dispatchQueue_accessMutex);
|
|
|
+ SIMPLEQ_INSERT_TAIL(&server->dispatchQueue, dc, next);
|
|
|
+ pthread_mutex_unlock(&server->dispatchQueue_accessMutex);
|
|
|
|
|
|
|
|
|
pthread_cond_broadcast(&server->dispatchQueue_condition);
|
|
@@ -301,8 +305,9 @@ UA_Server_run_startup(UA_Server *server) {
|
|
|
#ifdef UA_ENABLE_MULTITHREADING
|
|
|
UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_SERVER,
|
|
|
"Spinning up %u worker thread(s)", server->config.nThreads);
|
|
|
- pthread_cond_init(&server->dispatchQueue_condition, 0);
|
|
|
- pthread_mutex_init(&server->dispatchQueue_mutex, 0);
|
|
|
+ pthread_mutex_init(&server->dispatchQueue_accessMutex, NULL);
|
|
|
+ pthread_cond_init(&server->dispatchQueue_condition, NULL);
|
|
|
+ pthread_mutex_init(&server->dispatchQueue_conditionMutex, NULL);
|
|
|
server->workers = (UA_Worker*)UA_malloc(server->config.nThreads * sizeof(UA_Worker));
|
|
|
if(!server->workers)
|
|
|
return UA_STATUSCODE_BADOUTOFMEMORY;
|