diff options
author | Juergen Gehring <juergen.gehring@bmw.de> | 2014-12-10 11:17:20 +0100 |
---|---|---|
committer | Juergen Gehring <juergen.gehring@bmw.de> | 2014-12-10 11:17:20 +0100 |
commit | 83780c8b09ebf85d86f71971f3931028f6253d84 (patch) | |
tree | d91d8c025e4e7d341f1fdcdfae098280ef913b82 | |
parent | 3372155b32a2cf3b05e1a2a13f6f8413069de33f (diff) | |
download | genivi-common-api-dbus-runtime-83780c8b09ebf85d86f71971f3931028f6253d84.tar.gz |
Bugfix for race condition in sendDBusMessageWithReplyAsync.2.1.6-p2
The cause for this bug seems to be the order of the calls dbus_connection_send_with_reply and dbus_pending_call_set_notify.
It should be possible to call the notification for the reply first and then the function.
The standard libdbus API however does not provide this functionality.
Therefore a patch for libdbus is provided (see the directories dbus-1.4.26 or dbus-1.6.28 or dbus-1.8.12.
The patch can be applied by calling:
patch -p1 < path / to / dbus_connection_send_with_reply_set_notify.patch
in the dbus subdirectory of the DBus source code. The patch adds the new function: dbus_connection_send_with_reply_set_notify to the libdbus API.
This patch is necessary for the bugfix in DBusConnection.
4 files changed, 584 insertions, 16 deletions
diff --git a/dbus-patches/dbus-1.4.26/dbus_connection_send_with_reply_set_notify.patch b/dbus-patches/dbus-1.4.26/dbus_connection_send_with_reply_set_notify.patch new file mode 100644 index 0000000..c05d4e8 --- /dev/null +++ b/dbus-patches/dbus-1.4.26/dbus_connection_send_with_reply_set_notify.patch @@ -0,0 +1,192 @@ +diff -upr dbus_orig/dbus-connection.c dbus_mod/dbus-connection.c +--- dbus_orig/dbus-connection.c 2012-09-29 15:03:46.000000000 +0200 ++++ dbus_mod/dbus-connection.c 2014-12-04 16:00:22.451864843 +0100 +@@ -3440,6 +3440,168 @@ dbus_connection_send_with_reply (DBusCon + } + + /** ++ * Queues a message to send, as with dbus_connection_send(), ++ * but also returns a #DBusPendingCall used to receive a reply to the ++ * message. If no reply is received in the given timeout_milliseconds, ++ * this function expires the pending reply and generates a synthetic ++ * error reply (generated in-process, not by the remote application) ++ * indicating that a timeout occurred. ++ * ++ * Sets a notification function to be called when the reply is ++ * received or the pending call times out. ++ * ++ * A #DBusPendingCall will see a reply message before any filters or ++ * registered object path handlers. See dbus_connection_dispatch() for ++ * details on when handlers are run. ++ * ++ * A #DBusPendingCall will always see exactly one reply message, ++ * unless it's cancelled with dbus_pending_call_cancel(). ++ * ++ * If #NULL is passed for the pending_return, the #DBusPendingCall ++ * will still be generated internally, and used to track ++ * the message reply timeout. This means a timeout error will ++ * occur if no reply arrives, unlike with dbus_connection_send(). ++ * ++ * If -1 is passed for the timeout, a sane default timeout is used. -1 ++ * is typically the best value for the timeout for this reason, unless ++ * you want a very short or very long timeout. If #DBUS_TIMEOUT_INFINITE is ++ * passed for the timeout, no timeout will be set and the call will block ++ * forever. ++ * ++ * @warning if the connection is disconnected or you try to send Unix ++ * file descriptors on a connection that does not support them, the ++ * #DBusPendingCall will be set to #NULL, so be careful with this. ++ * ++ * @param connection the connection ++ * @param message the message to send ++ * @param pending_return return location for a #DBusPendingCall ++ * object, or #NULL if connection is disconnected or when you try to ++ * send Unix file descriptors on a connection that does not support ++ * them. ++ * @param function0 notifier function ++ * @param user_data0 data to pass to notifier function ++ * @param free_user_data0 function to free the user data ++ * @param timeout_milliseconds timeout in milliseconds, -1 (or ++ * #DBUS_TIMEOUT_USE_DEFAULT) for default or #DBUS_TIMEOUT_INFINITE for no ++ * timeout ++ * @returns #FALSE if no memory, #TRUE otherwise. ++ * ++ */ ++dbus_bool_t ++dbus_connection_send_with_reply_set_notify (DBusConnection *connection, ++ DBusMessage *message, ++ DBusPendingCall **pending_return, ++ DBusPendingCallNotifyFunction function0, ++ void *user_data0, ++ DBusFreeFunction free_user_data0, ++ int timeout_milliseconds) ++{ ++ ++ DBusPendingCall *pending; ++ dbus_int32_t serial = -1; ++ DBusDispatchStatus status; ++ ++ _dbus_return_val_if_fail (connection != NULL, FALSE); ++ _dbus_return_val_if_fail (message != NULL, FALSE); ++ _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); ++ ++ if (pending_return) ++ *pending_return = NULL; ++ ++ CONNECTION_LOCK (connection); ++ ++#ifdef HAVE_UNIX_FD_PASSING ++ ++ if (!_dbus_transport_can_pass_unix_fd(connection->transport) && ++ message->n_unix_fds > 0) ++ { ++ /* Refuse to send fds on a connection that cannot handle ++ them. Unfortunately we cannot return a proper error here, so ++ the best we can do is return TRUE but leave *pending_return ++ as NULL. */ ++ CONNECTION_UNLOCK (connection); ++ return TRUE; ++ } ++ ++#endif ++ ++ if (!_dbus_connection_get_is_connected_unlocked (connection)) ++ { ++ CONNECTION_UNLOCK (connection); ++ ++ return TRUE; ++ } ++ ++ pending = _dbus_pending_call_new_unlocked (connection, ++ timeout_milliseconds, ++ reply_handler_timeout); ++ ++ if (pending == NULL) ++ { ++ CONNECTION_UNLOCK (connection); ++ return FALSE; ++ } ++ ++ if (!dbus_pending_call_set_notify(pending, function0, user_data0, free_user_data0)) ++ { ++ CONNECTION_UNLOCK (connection); ++ return FALSE; ++ } ++ ++ /* Assign a serial to the message */ ++ serial = dbus_message_get_serial (message); ++ if (serial == 0) ++ { ++ serial = _dbus_connection_get_next_client_serial (connection); ++ dbus_message_set_serial (message, serial); ++ } ++ ++ if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial)) ++ goto error; ++ ++ /* Insert the serial in the pending replies hash; ++ * hash takes a refcount on DBusPendingCall. ++ * Also, add the timeout. ++ */ ++ if (!_dbus_connection_attach_pending_call_unlocked (connection, ++ pending)) ++ goto error; ++ ++ if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL)) ++ { ++ _dbus_connection_detach_pending_call_and_unlock (connection, ++ pending); ++ goto error_unlocked; ++ } ++ ++ if (pending_return) ++ *pending_return = pending; /* hand off refcount */ ++ else ++ { ++ _dbus_connection_detach_pending_call_unlocked (connection, pending); ++ /* we still have a ref to the pending call in this case, we unref ++ * after unlocking, below ++ */ ++ } ++ ++ status = _dbus_connection_get_dispatch_status_unlocked (connection); ++ ++ /* this calls out to user code */ ++ _dbus_connection_update_dispatch_status_and_unlock (connection, status); ++ ++ if (pending_return == NULL) ++ dbus_pending_call_unref (pending); ++ ++ return TRUE; ++ ++ error: ++ CONNECTION_UNLOCK (connection); ++ error_unlocked: ++ dbus_pending_call_unref (pending); ++ return FALSE; ++} ++ ++/** + * Sends a message and blocks a certain time period while waiting for + * a reply. This function does not reenter the main loop, + * i.e. messages other than the reply are queued up but not +diff -upr dbus_orig/dbus-connection.h dbus_mod/dbus-connection.h +--- dbus_orig/dbus-connection.h 2012-09-29 15:03:46.000000000 +0200 ++++ dbus_mod/dbus-connection.h 2014-12-04 16:03:12.535858076 +0100 +@@ -228,6 +228,16 @@ dbus_bool_t dbus_connection_send_ + DBusMessage *message, + DBusPendingCall **pending_return, + int timeout_milliseconds); ++ ++DBUS_EXPORT ++dbus_bool_t dbus_connection_send_with_reply_set_notify (DBusConnection *connection, ++ DBusMessage *message, ++ DBusPendingCall **pending_return, ++ DBusPendingCallNotifyFunction function0, ++ void *user_data0, ++ DBusFreeFunction free_user_data0, ++ int timeout_milliseconds); ++ + DBUS_EXPORT + DBusMessage * dbus_connection_send_with_reply_and_block (DBusConnection *connection, + DBusMessage *message, diff --git a/dbus-patches/dbus-1.6.28/dbus_connection_send_with_reply_set_notify.patch b/dbus-patches/dbus-1.6.28/dbus_connection_send_with_reply_set_notify.patch new file mode 100644 index 0000000..2cd6c67 --- /dev/null +++ b/dbus-patches/dbus-1.6.28/dbus_connection_send_with_reply_set_notify.patch @@ -0,0 +1,192 @@ +diff -upr dbus_orig/dbus-connection.c dbus_mod/dbus-connection.c +--- dbus_orig/dbus-connection.c 2014-09-15 20:22:15.000000000 +0200 ++++ dbus_mod/dbus-connection.c 2014-12-04 15:25:21.983948426 +0100 +@@ -3482,6 +3482,168 @@ dbus_connection_send_with_reply (DBusCon + } + + /** ++ * Queues a message to send, as with dbus_connection_send(), ++ * but also returns a #DBusPendingCall used to receive a reply to the ++ * message. If no reply is received in the given timeout_milliseconds, ++ * this function expires the pending reply and generates a synthetic ++ * error reply (generated in-process, not by the remote application) ++ * indicating that a timeout occurred. ++ * ++ * Sets a notification function to be called when the reply is ++ * received or the pending call times out. ++ * ++ * A #DBusPendingCall will see a reply message before any filters or ++ * registered object path handlers. See dbus_connection_dispatch() for ++ * details on when handlers are run. ++ * ++ * A #DBusPendingCall will always see exactly one reply message, ++ * unless it's cancelled with dbus_pending_call_cancel(). ++ * ++ * If #NULL is passed for the pending_return, the #DBusPendingCall ++ * will still be generated internally, and used to track ++ * the message reply timeout. This means a timeout error will ++ * occur if no reply arrives, unlike with dbus_connection_send(). ++ * ++ * If -1 is passed for the timeout, a sane default timeout is used. -1 ++ * is typically the best value for the timeout for this reason, unless ++ * you want a very short or very long timeout. If #DBUS_TIMEOUT_INFINITE is ++ * passed for the timeout, no timeout will be set and the call will block ++ * forever. ++ * ++ * @warning if the connection is disconnected or you try to send Unix ++ * file descriptors on a connection that does not support them, the ++ * #DBusPendingCall will be set to #NULL, so be careful with this. ++ * ++ * @param connection the connection ++ * @param message the message to send ++ * @param pending_return return location for a #DBusPendingCall ++ * object, or #NULL if connection is disconnected or when you try to ++ * send Unix file descriptors on a connection that does not support ++ * them. ++ * @param function0 notifier function ++ * @param user_data0 data to pass to notifier function ++ * @param free_user_data0 function to free the user data ++ * @param timeout_milliseconds timeout in milliseconds, -1 (or ++ * #DBUS_TIMEOUT_USE_DEFAULT) for default or #DBUS_TIMEOUT_INFINITE for no ++ * timeout ++ * @returns #FALSE if no memory, #TRUE otherwise. ++ * ++ */ ++dbus_bool_t ++dbus_connection_send_with_reply_set_notify (DBusConnection *connection, ++ DBusMessage *message, ++ DBusPendingCall **pending_return, ++ DBusPendingCallNotifyFunction function0, ++ void *user_data0, ++ DBusFreeFunction free_user_data0, ++ int timeout_milliseconds) ++{ ++ ++ DBusPendingCall *pending; ++ dbus_int32_t serial = -1; ++ DBusDispatchStatus status; ++ ++ _dbus_return_val_if_fail (connection != NULL, FALSE); ++ _dbus_return_val_if_fail (message != NULL, FALSE); ++ _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); ++ ++ if (pending_return) ++ *pending_return = NULL; ++ ++ CONNECTION_LOCK (connection); ++ ++#ifdef HAVE_UNIX_FD_PASSING ++ ++ if (!_dbus_transport_can_pass_unix_fd(connection->transport) && ++ message->n_unix_fds > 0) ++ { ++ /* Refuse to send fds on a connection that cannot handle ++ them. Unfortunately we cannot return a proper error here, so ++ the best we can do is return TRUE but leave *pending_return ++ as NULL. */ ++ CONNECTION_UNLOCK (connection); ++ return TRUE; ++ } ++ ++#endif ++ ++ if (!_dbus_connection_get_is_connected_unlocked (connection)) ++ { ++ CONNECTION_UNLOCK (connection); ++ ++ return TRUE; ++ } ++ ++ pending = _dbus_pending_call_new_unlocked (connection, ++ timeout_milliseconds, ++ reply_handler_timeout); ++ ++ if (pending == NULL) ++ { ++ CONNECTION_UNLOCK (connection); ++ return FALSE; ++ } ++ ++ if (!dbus_pending_call_set_notify(pending, function0, user_data0, free_user_data0)) ++ { ++ CONNECTION_UNLOCK (connection); ++ return FALSE; ++ } ++ ++ /* Assign a serial to the message */ ++ serial = dbus_message_get_serial (message); ++ if (serial == 0) ++ { ++ serial = _dbus_connection_get_next_client_serial (connection); ++ dbus_message_set_serial (message, serial); ++ } ++ ++ if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial)) ++ goto error; ++ ++ /* Insert the serial in the pending replies hash; ++ * hash takes a refcount on DBusPendingCall. ++ * Also, add the timeout. ++ */ ++ if (!_dbus_connection_attach_pending_call_unlocked (connection, ++ pending)) ++ goto error; ++ ++ if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL)) ++ { ++ _dbus_connection_detach_pending_call_and_unlock (connection, ++ pending); ++ goto error_unlocked; ++ } ++ ++ if (pending_return) ++ *pending_return = pending; /* hand off refcount */ ++ else ++ { ++ _dbus_connection_detach_pending_call_unlocked (connection, pending); ++ /* we still have a ref to the pending call in this case, we unref ++ * after unlocking, below ++ */ ++ } ++ ++ status = _dbus_connection_get_dispatch_status_unlocked (connection); ++ ++ /* this calls out to user code */ ++ _dbus_connection_update_dispatch_status_and_unlock (connection, status); ++ ++ if (pending_return == NULL) ++ dbus_pending_call_unref (pending); ++ ++ return TRUE; ++ ++ error: ++ CONNECTION_UNLOCK (connection); ++ error_unlocked: ++ dbus_pending_call_unref (pending); ++ return FALSE; ++} ++ ++/** + * Sends a message and blocks a certain time period while waiting for + * a reply. This function does not reenter the main loop, + * i.e. messages other than the reply are queued up but not +diff -upr dbus_orig/dbus-connection.h dbus_mod/dbus-connection.h +--- dbus_orig/dbus-connection.h 2014-09-15 20:19:42.000000000 +0200 ++++ dbus_mod/dbus-connection.h 2014-12-04 15:27:29.115943367 +0100 +@@ -229,6 +229,16 @@ dbus_bool_t dbus_connection_send_ + DBusMessage *message, + DBusPendingCall **pending_return, + int timeout_milliseconds); ++ ++DBUS_EXPORT ++dbus_bool_t dbus_connection_send_with_reply_set_notify (DBusConnection *connection, ++ DBusMessage *message, ++ DBusPendingCall **pending_return, ++ DBusPendingCallNotifyFunction function0, ++ void *user_data0, ++ DBusFreeFunction free_user_data0, ++ int timeout_milliseconds); ++ + DBUS_EXPORT + DBusMessage * dbus_connection_send_with_reply_and_block (DBusConnection *connection, + DBusMessage *message, diff --git a/dbus-patches/dbus-1.8.12/dbus_connection_send_with_reply_set_notify.patch b/dbus-patches/dbus-1.8.12/dbus_connection_send_with_reply_set_notify.patch new file mode 100644 index 0000000..c9e841c --- /dev/null +++ b/dbus-patches/dbus-1.8.12/dbus_connection_send_with_reply_set_notify.patch @@ -0,0 +1,192 @@ +diff -upr dbus_orig/dbus-connection.c dbus_mod/dbus-connection.c +--- dbus_orig/dbus-connection.c 2014-11-04 15:51:05.000000000 +0100 ++++ dbus_mod/dbus-connection.c 2014-12-04 15:05:03.523996912 +0100 +@@ -3500,6 +3500,168 @@ dbus_connection_send_with_reply (DBusCon + } + + /** ++ * Queues a message to send, as with dbus_connection_send(), ++ * but also returns a #DBusPendingCall used to receive a reply to the ++ * message. If no reply is received in the given timeout_milliseconds, ++ * this function expires the pending reply and generates a synthetic ++ * error reply (generated in-process, not by the remote application) ++ * indicating that a timeout occurred. ++ * ++ * Sets a notification function to be called when the reply is ++ * received or the pending call times out. ++ * ++ * A #DBusPendingCall will see a reply message before any filters or ++ * registered object path handlers. See dbus_connection_dispatch() for ++ * details on when handlers are run. ++ * ++ * A #DBusPendingCall will always see exactly one reply message, ++ * unless it's cancelled with dbus_pending_call_cancel(). ++ * ++ * If #NULL is passed for the pending_return, the #DBusPendingCall ++ * will still be generated internally, and used to track ++ * the message reply timeout. This means a timeout error will ++ * occur if no reply arrives, unlike with dbus_connection_send(). ++ * ++ * If -1 is passed for the timeout, a sane default timeout is used. -1 ++ * is typically the best value for the timeout for this reason, unless ++ * you want a very short or very long timeout. If #DBUS_TIMEOUT_INFINITE is ++ * passed for the timeout, no timeout will be set and the call will block ++ * forever. ++ * ++ * @warning if the connection is disconnected or you try to send Unix ++ * file descriptors on a connection that does not support them, the ++ * #DBusPendingCall will be set to #NULL, so be careful with this. ++ * ++ * @param connection the connection ++ * @param message the message to send ++ * @param pending_return return location for a #DBusPendingCall ++ * object, or #NULL if connection is disconnected or when you try to ++ * send Unix file descriptors on a connection that does not support ++ * them. ++ * @param function0 notifier function ++ * @param user_data0 data to pass to notifier function ++ * @param free_user_data0 function to free the user data ++ * @param timeout_milliseconds timeout in milliseconds, -1 (or ++ * #DBUS_TIMEOUT_USE_DEFAULT) for default or #DBUS_TIMEOUT_INFINITE for no ++ * timeout ++ * @returns #FALSE if no memory, #TRUE otherwise. ++ * ++ */ ++dbus_bool_t ++dbus_connection_send_with_reply_set_notify (DBusConnection *connection, ++ DBusMessage *message, ++ DBusPendingCall **pending_return, ++ DBusPendingCallNotifyFunction function0, ++ void *user_data0, ++ DBusFreeFunction free_user_data0, ++ int timeout_milliseconds) ++{ ++ ++ DBusPendingCall *pending; ++ dbus_int32_t serial = -1; ++ DBusDispatchStatus status; ++ ++ _dbus_return_val_if_fail (connection != NULL, FALSE); ++ _dbus_return_val_if_fail (message != NULL, FALSE); ++ _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); ++ ++ if (pending_return) ++ *pending_return = NULL; ++ ++ CONNECTION_LOCK (connection); ++ ++#ifdef HAVE_UNIX_FD_PASSING ++ ++ if (!_dbus_transport_can_pass_unix_fd(connection->transport) && ++ message->n_unix_fds > 0) ++ { ++ /* Refuse to send fds on a connection that cannot handle ++ them. Unfortunately we cannot return a proper error here, so ++ the best we can do is return TRUE but leave *pending_return ++ as NULL. */ ++ CONNECTION_UNLOCK (connection); ++ return TRUE; ++ } ++ ++#endif ++ ++ if (!_dbus_connection_get_is_connected_unlocked (connection)) ++ { ++ CONNECTION_UNLOCK (connection); ++ ++ return TRUE; ++ } ++ ++ pending = _dbus_pending_call_new_unlocked (connection, ++ timeout_milliseconds, ++ reply_handler_timeout); ++ ++ if (pending == NULL) ++ { ++ CONNECTION_UNLOCK (connection); ++ return FALSE; ++ } ++ ++ if (!dbus_pending_call_set_notify(pending, function0, user_data0, free_user_data0)) ++ { ++ CONNECTION_UNLOCK (connection); ++ return FALSE; ++ } ++ ++ /* Assign a serial to the message */ ++ serial = dbus_message_get_serial (message); ++ if (serial == 0) ++ { ++ serial = _dbus_connection_get_next_client_serial (connection); ++ dbus_message_set_serial (message, serial); ++ } ++ ++ if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial)) ++ goto error; ++ ++ /* Insert the serial in the pending replies hash; ++ * hash takes a refcount on DBusPendingCall. ++ * Also, add the timeout. ++ */ ++ if (!_dbus_connection_attach_pending_call_unlocked (connection, ++ pending)) ++ goto error; ++ ++ if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL)) ++ { ++ _dbus_connection_detach_pending_call_and_unlock (connection, ++ pending); ++ goto error_unlocked; ++ } ++ ++ if (pending_return) ++ *pending_return = pending; /* hand off refcount */ ++ else ++ { ++ _dbus_connection_detach_pending_call_unlocked (connection, pending); ++ /* we still have a ref to the pending call in this case, we unref ++ * after unlocking, below ++ */ ++ } ++ ++ status = _dbus_connection_get_dispatch_status_unlocked (connection); ++ ++ /* this calls out to user code */ ++ _dbus_connection_update_dispatch_status_and_unlock (connection, status); ++ ++ if (pending_return == NULL) ++ dbus_pending_call_unref (pending); ++ ++ return TRUE; ++ ++ error: ++ CONNECTION_UNLOCK (connection); ++ error_unlocked: ++ dbus_pending_call_unref (pending); ++ return FALSE; ++} ++ ++/** + * Sends a message and blocks a certain time period while waiting for + * a reply. This function does not reenter the main loop, + * i.e. messages other than the reply are queued up but not +diff -upr dbus_orig/dbus-connection.h dbus_mod/dbus-connection.h +--- dbus_orig/dbus-connection.h 2014-11-04 15:51:05.000000000 +0100 ++++ dbus_mod/dbus-connection.h 2014-12-04 15:10:10.283984705 +0100 +@@ -229,6 +229,16 @@ dbus_bool_t dbus_connection_send_ + DBusMessage *message, + DBusPendingCall **pending_return, + int timeout_milliseconds); ++ ++DBUS_EXPORT ++dbus_bool_t dbus_connection_send_with_reply_set_notify (DBusConnection *connection, ++ DBusMessage *message, ++ DBusPendingCall **pending_return, ++ DBusPendingCallNotifyFunction function0, ++ void *user_data0, ++ DBusFreeFunction free_user_data0, ++ int timeout_milliseconds); ++ + DBUS_EXPORT + DBusMessage * dbus_connection_send_with_reply_and_block (DBusConnection *connection, + DBusMessage *message, diff --git a/src/CommonAPI/DBus/DBusConnection.cpp b/src/CommonAPI/DBus/DBusConnection.cpp index 6deb376..c087e64 100644 --- a/src/CommonAPI/DBus/DBusConnection.cpp +++ b/src/CommonAPI/DBus/DBusConnection.cpp @@ -556,25 +556,17 @@ std::future<CallStatus> DBusConnection::sendDBusMessageWithReplyAsync( dbus_bool_t libdbusSuccess; suspendDispatching(); - libdbusSuccess = dbus_connection_send_with_reply(libdbusConnection_, - dbusMessage.libdbusMessage_, - &libdbusPendingCall, - timeoutMilliseconds); + + libdbusSuccess = dbus_connection_send_with_reply_set_notify(libdbusConnection_, + dbusMessage.libdbusMessage_, + &libdbusPendingCall, + onLibdbusPendingCallNotifyThunk, + dbusMessageReplyAsyncHandler.get(), + onLibdbusDataCleanup, + timeoutMilliseconds); if (!libdbusSuccess || !libdbusPendingCall) { dbusMessageReplyAsyncHandler->onDBusMessageReply(CallStatus::CONNECTION_FAILED, dbusMessage.createMethodError(DBUS_ERROR_DISCONNECTED)); - resumeDispatching(); - return dbusMessageReplyAsyncHandler->getFuture(); - } - - libdbusSuccess = dbus_pending_call_set_notify( - libdbusPendingCall, - onLibdbusPendingCallNotifyThunk, - dbusMessageReplyAsyncHandler.get(), - onLibdbusDataCleanup); - - if (!libdbusSuccess) { - dbusMessageReplyAsyncHandler->onDBusMessageReply(CallStatus::OUT_OF_MEMORY, dbusMessage); dbus_pending_call_unref(libdbusPendingCall); resumeDispatching(); return dbusMessageReplyAsyncHandler->getFuture(); |