<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p><span style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Hello Community,</span><br>
</p>
<div style="color: rgb(0, 0, 0);">
<div>
<div id="divtagdefaultwrapper" dir="ltr" style="font-size:12pt; color:#000000; font-family:Calibri,Helvetica,sans-serif">
<p><br>
</p>
<p>I have developed a C++ application (for Bluetooth Low energy) using DBUS on Linux. </p>
<p><br>
</p>
<p class="">Earlier, I was calling dbus_connection_* function in different threads and was observing unexpected behaviour. </p>
<p>I have changed the way I was managing single DBus connection across different threads (as suggested by <span>Thiago Macieira. Thanks to him</span>).</p>
<p><br>
</p>
<p></p>
<p style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;" class="">
I am now calling dbus_connection_* from a single thread (Thread A). Other threads (Thread B, C ...) in my application prepares, queues DBusMessages in a thread safe queue and then blocks for replies (using mutex, conditional variables). </p>
<p style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;" class="">
<br>
</p>
<p style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;" class="">
The thread A periodically deque (<span style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">from thread safe queue</span>) and sends those messages and sets pending call callbacks and then return. The Thread A is running
<b>glib event loop</b>. The callbacks are delivered on Thread A by glib event loop. I am using glib and it</p>
<div class="flipthis-wrapper"><span style="font-family: Calibri, Helvetica, sans-serif; font-size: 16px;" class=""> is exactly similar to "bluetoothctl" event loop implementation: </span></div>
<a href="https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/gdbus/mainloop.c" class="OWAAutoLink" id="LPlnk962081" previewremoved="true" style="font-family: Calibri, Helvetica, sans-serif; font-size: 16px;">https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/gdbus/mainloop.c</a><span style="font-family: Calibri, Helvetica, sans-serif; font-size: 16px;"> .
The watch, timeout implementation and dispatching of dbus messages are handled by glib event loop.</span>
<p></p>
<p style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;" class="">
<br>
</p>
<p style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;" class="">
I have tested it and run valgrind and it didn't show anything unexpected. Looks like everything is working but still I want to be sure if this is the right way to handle it. Do I need to call dbus_threads_init()? </p>
<p style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</p>
<p style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
As far as I have gone through dbus source code, I think dbus_message_* API should be thread-safe and re-entrant. Please help.</p>
<p style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</p>
<p style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
Below are the few functions:</p>
<p style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</p>
<p style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span style="color: rgb(75, 165, 36);">// Called in Thread other than Thread A</span></p>
<p style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
</p>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
DBusMessage *DBusClient::queue_message_and_block(DBusMessage *p_message)</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
{</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>DBusMessage *p_reply;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>dbus_message_ref(p_message);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>struct cb_data_s *p_data = new struct cb_data_s;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>if (p_data == nullptr)</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>return nullptr;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>{</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>std::unique_lock<std::mutex> reply_guard(p_data->mutex);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>p_data->status = false;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>p_data->p_reply = nullptr;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>{</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>std::lock_guard<std::mutex> guard(_queue_mutex);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>_queue.push_back(std::make_pair(p_message, p_data));</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>}</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span></div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>p_data->cond.wait(reply_guard, [&] { return p_data->status.load(); });</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>p_reply = p_data->p_reply;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>dbus_message_unref(p_message);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>}</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span></div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>delete p_data;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>return p_reply;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
}</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span style="color: rgb(75, 165, 36);">// Called periodically by glib in Thread A.</span></div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
gboolean DBusClient::periodic_dbus_message_dispatch(gpointer user_data)</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
{</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>DBusMessage *p_msg = nullptr;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>struct cb_data_s *p_data = nullptr;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span></div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>std::lock_guard<std::mutex> guard(_queue_mutex);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>while (_queue.size()) {</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>std::pair<DBusMessage *, struct cb_data_s *> pair = _queue.front();</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>_queue.pop_front();</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>p_msg = pair.first;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>p_data = pair.second;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>DBusPendingCall *p_call;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>dbus_connection_send_with_reply(_p_conn, p_msg, &p_call, METHOD_CALL_TIMEOUT);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>dbus_pending_call_set_notify(p_call, pending_callback, reinterpret_cast<void *>(p_data), nullptr);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>dbus_pending_call_unref(p_call);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>dbus_message_unref(p_msg);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>}</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>return TRUE;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
}</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span style="color: rgb(75, 165, 36);">// This callback should be dispatched in thread A.</span></div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
void DBusClient::pending_callback(DBusPendingCall *p_call, void *data)</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
{</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>struct cb_data_s *cb_data = reinterpret_cast<struct cb_data_s *>(data);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>if (cb_data == nullptr)</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>return;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>std::lock_guard<std::mutex> guard(cb_data->mutex);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>DBusMessage *p_reply = dbus_pending_call_steal_reply(p_call);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>DBusError error;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>dbus_error_init(&error);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>if (dbus_set_error_from_message(&error, p_reply) == TRUE) {</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>dbus_error_free(&error);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>dbus_message_unref(p_reply);</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>p_reply = nullptr;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>}</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>cb_data->p_reply = p_reply;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>cb_data->status = true;</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
<span class="x_Apple-tab-span" style="white-space: pre;"></span>cb_data->cond.notify_all();</div>
<div style="font-family: Calibri, Helvetica, sans-serif, serif, EmojiFont; font-size: 16px;">
}</div>
<p></p>
<p><br>
</p>
<p class=""></p>
</div>
</div>
</div>
</div>
</body>
</html>