Thread safety of UA_Client_runAsync()

852 views
Skip to first unread message

nat...@gmail.com

unread,
Jun 21, 2018, 6:51:46 AM6/21/18
to open62541
Hi to all,

I would like to know to what an extent (if at all) calling open62541 functions is safe while UA_Client_runAsync() is running in another thread.

Context: I have a piece of software in which I need to relay data transfers (reads, writes, subscriptions) between user code and a backend OPC-UA client. The idea was to create an UA_Client along with a thread that would call UA_Client_runAsync() in a loop. Asynchronous calls would then be called from user code, and my backend would dispatch the results when they arrived.

However, it quickly became clear that at least some open62541 functionality could not be used concurrently while UA_Client_runAsync() was running in the backend thread. For one, registering a subscription and creating a monitored item resulted in sporadic malfunctions. If I ensured that UA_Client_runAsync() was not active at the same time, everything went well, so it seemed to be concurrency-related. At this point I started questioning whether calling UA_Client_AsyncService_read() or UA_Client_AsyncService_write() – or any other UA_Client function for that matter – concurrently with UA_Client_runAsync() was allowed at all.

I'm using the amalgamated source, version 0.3-rc1.

Kind regards,
Andrej Lajovic

Stefan Profanter

unread,
Jun 25, 2018, 10:27:59 AM6/25/18
to open62541
Hi Andrej,
in general the whole open62541 stack ist not thread-safe, since the multithreading feature is currently experimental and mainly on the server side.

Therefore you should make sure that one client instance is either only used by one thread or you use mutexes.

Note that `UA_Client_runAsync()` is from Version 0.3.

In this PR the async handling of the client was improved a lot but is only in current master:

An example can be found here:

Using this, you still need to make sure you are mutexing the client.

BR
Stefan

nat...@gmail.com

unread,
Jun 26, 2018, 7:44:01 AM6/26/18
to open62541
Hi Stefan,

thanks for your answer.

in general the whole open62541 stack ist not thread-safe, since the multithreading feature is currently experimental and mainly on the server side.
Therefore you should make sure that one client instance is either only used by one thread or you use mutexes.

I thought so. What bothers me the most is that I obviously cannot call any asynchronous functions while UA_Client_runAsync() (or, in version 0.4, UA_Client_run_iterate()) is running, but I also have no means to interrupt the UA_Client_run_iterate() function before the timeout period has elapsed. This means that if I have a background thread calling UA_Client_run_iterate() in a loop, any other thread wanting to do an OPC-UA operation will have no other option than to block until the current call to UA_Client_run_iterate() finishes. Since the essential purpose of asynchronous calls is to be non-blocking, this somehow undermines the whole concept.

The only option that comes to my mind is calling UA_Client_run_iterate() with a very short timeout in order to reduce the maximum blocking time. But this is hardly an elegant solution.

Cheers,
Andrej
Reply all
Reply to author
Forward
0 new messages