summaryrefslogtreecommitdiff
path: root/desktop/source
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2017-10-25 17:09:17 +0200
committerStephan Bergmann <sbergman@redhat.com>2017-10-25 17:09:17 +0200
commitdc3ff192f3f048059cf149f416d0b237eb33b014 (patch)
tree47a6beb71541c6e21da2d18d89bcc1aa4c6791f6 /desktop/source
parent0ce75cde0a0bdf4b3c23044e713f906a765e8a8a (diff)
Avoid further unwanted interference of DbusIpcThread::execute/close
...after 38081c0884b64ed1132047973b4dccc42d548c89 "Avoid race between DbusIpcThread::close and DbusIpcThread::execute" Change-Id: I812f53525f4c2c051781321dac7096e3bf0d7054
Diffstat (limited to 'desktop/source')
-rw-r--r--desktop/source/app/officeipcthread.cxx84
1 files changed, 54 insertions, 30 deletions
diff --git a/desktop/source/app/officeipcthread.cxx b/desktop/source/app/officeipcthread.cxx
index b2380c0f9c43..b14cde421d24 100644
--- a/desktop/source/app/officeipcthread.cxx
+++ b/desktop/source/app/officeipcthread.cxx
@@ -449,6 +449,7 @@ private:
void close() override;
DbusConnectionHolder connection_;
+ osl::Condition closeDone_;
};
RequestHandler::Status DbusIpcThread::enable(rtl::Reference<IpcThread> * thread)
@@ -569,6 +570,19 @@ void DbusIpcThread::execute()
if (dbus_message_is_method_call(
msg.message, "org.libreoffice.LibreOfficeIpcIfc0", "Close"))
{
+ DbusMessageHolder repl(dbus_message_new_method_return(msg.message));
+ if (repl.message == nullptr) {
+ SAL_WARN(
+ "desktop.app", "dbus_message_new_method_return failed");
+ } else {
+ dbus_uint32_t serial = 0;
+ if (!dbus_connection_send(
+ connection_.connection, repl.message, &serial)) {
+ SAL_WARN("desktop.app", "dbus_connection_send failed");
+ } else {
+ dbus_connection_flush(connection_.connection);
+ }
+ }
break;
}
if (!dbus_message_is_method_call(
@@ -612,6 +626,7 @@ void DbusIpcThread::execute()
}
dbus_connection_flush(connection_.connection);
}
+ closeDone_.wait();
DBusError e;
dbus_error_init(&e);
int n = dbus_bus_release_name(
@@ -639,37 +654,46 @@ void DbusIpcThread::execute()
}
void DbusIpcThread::close() {
- assert(connection_.connection != nullptr);
- DBusError e;
- dbus_error_init(&e);
- // Let DbusIpcThread::execute return from dbus_connection_read_write; for
- // now, just abort on failure (the process would otherwise block, with
- // DbusIpcThread::execute hanging in dbus_connection_read_write); this
- // apparently needs a more DBus-y design anyway:
- DbusConnectionHolder con(dbus_bus_get_private(DBUS_BUS_SESSION, &e));
- assert((con.connection == nullptr) == bool(dbus_error_is_set(&e)));
- if (con.connection == nullptr) {
- SAL_WARN(
- "desktop.app",
- "dbus_bus_get_private failed with: " << e.name << ": "
- << e.message);
- dbus_error_free(&e);
- std::abort();
- }
- DbusMessageHolder msg(
- dbus_message_new_method_call(
- "org.libreoffice.LibreOfficeIpc0",
- "/org/libreoffice/LibreOfficeIpc0",
- "org.libreoffice.LibreOfficeIpcIfc0", "Close"));
- if (msg.message == nullptr) {
- SAL_WARN("desktop.app", "dbus_message_new_method_call failed");
- std::abort();
- }
- if (!dbus_connection_send(con.connection, msg.message, nullptr)) {
- SAL_WARN("desktop.app", "dbus_connection_send failed");
- std::abort();
+ {
+ assert(connection_.connection != nullptr);
+ DBusError e;
+ dbus_error_init(&e);
+ // Let DbusIpcThread::execute return from dbus_connection_read_write;
+ // for now, just abort on failure (the process would otherwise block,
+ // with DbusIpcThread::execute hanging in dbus_connection_read_write);
+ // this apparently needs a more DBus-y design anyway:
+ DbusConnectionHolder con(dbus_bus_get_private(DBUS_BUS_SESSION, &e));
+ assert((con.connection == nullptr) == bool(dbus_error_is_set(&e)));
+ if (con.connection == nullptr) {
+ SAL_WARN(
+ "desktop.app",
+ "dbus_bus_get_private failed with: " << e.name << ": "
+ << e.message);
+ dbus_error_free(&e);
+ std::abort();
+ }
+ DbusMessageHolder msg(
+ dbus_message_new_method_call(
+ "org.libreoffice.LibreOfficeIpc0",
+ "/org/libreoffice/LibreOfficeIpc0",
+ "org.libreoffice.LibreOfficeIpcIfc0", "Close"));
+ if (msg.message == nullptr) {
+ SAL_WARN("desktop.app", "dbus_message_new_method_call failed");
+ std::abort();
+ }
+ DbusMessageHolder repl(
+ dbus_connection_send_with_reply_and_block(
+ con.connection, msg.message, 0x7FFFFFFF, &e));
+ assert((repl.message == nullptr) == bool(dbus_error_is_set(&e)));
+ if (repl.message == nullptr) {
+ SAL_INFO(
+ "desktop.app",
+ "dbus_connection_send_with_reply_and_block failed with: "
+ << e.name << ": " << e.message);
+ dbus_error_free(&e);
+ }
}
- dbus_connection_flush(con.connection);
+ closeDone_.set();
}
#endif