On Wed, 7 Apr 2021 16:15:40 +0200
Post by Lennart Poettering Post by Carlo Wood
As you stated in the linked email, there is no global state.
So, I suppose that if I call any sd_bus_* function that
all that I have to take into account is that the data
that is passed to those functions is protected. If they
use different connections, then no data should be shared,
Not sure I grok the question.
It was just a repeat, stated differently.
I assume that anything related to the same sd_bus* object,
which includes sd_bus_message* objects that use that sd_bus*
can not be passed to more than one function at a time and
executed in parallel. But (which is what I stated above)
if the (associated) sd_bus* is different, then that is possible.
I think you already confirmed that this is possible.
So, my plan will be to add a "lock" per connection.
I have dbus::Connection objects and it will be very clear
which one any call to a sd_bus_* function is associated
with; so I can use those objects as "lock". I put lock between
quotes here because it won't be an ordinary mutex: a mutex
blocks other threads as long as the thread holds this mutex
(aka, is inside the function). That is quite long imho:
normally I try to keep mutexes that can block out other threads
for (much) less than a micro second. Longer than 10 micro
seconds is unacceptable (and wrong use of mutexes imho).
I invented a different concept to deal with threads with
my library: I run threaded code in 'tasks' which are then
basically executed single-threaded (not the same thread,
but one thread at a time runs a task). All variables that
a task deals with while running are private members of
the task object and there is therefore no locking needed
at all for those variables.
However, I decided against using a different sdbus connection
per thread for the simple reason that I do not keep track
of threads; I have tasks that when needing to run get cpu
time from an available thread. I could use one connection
per task, but that has (a lot of) overhead, since I create,
execute and destroy tasks a LOT. Aka, you'd get a new
connection for every sd_bus message. It seemed more logical
to me to make a connection and keep that alive; and reuse
it over and over for new messages. That way, in most cases,
I'll just have a single connection (ie, to the userbus)
without a repeat of the handshake all the time.
But since I have tasks for doing everything, like sending
a signal, or a method call, and those run in parallel at
the moment, the connection, aka sd_bus object, is used
by multiple threads concurrently at the moment, causing
more than one thread to enter the sd_bus library at the
time time for the same sd_bus object.