summaryrefslogtreecommitdiff
path: root/ucb/source/ucp/gio/gio_mount.cxx
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2019-05-09 09:21:24 +0200
committerStephan Bergmann <sbergman@redhat.com>2019-05-09 13:14:00 +0200
commit8a443fe0f4ab50e2156e2c7e0cf713f2949e3164 (patch)
tree73d5fd57929f6b1e7fdd8c00c3dfecc65d3397b1 /ucb/source/ucp/gio/gio_mount.cxx
parent82d018b402219b5452bb08aac2c060031bbc3298 (diff)
tdf#124962: Reduce risk of g_main_loop_run from within gio MountOperation
Using g_main_loop_run here appears to be inherently necessary for the g_file_mount_enclosing_volume/g_file_mount_enclosing_volume_finish protocol, but has at least two problems: For one, it temporarily drops the SolarMutex (if it was held by the current thread), causing the usual integrity issues caused by an inner stack frame temporarily releasing the SolarMutex that is held by some unsuspecting caller. This is an inherent problem of our broken SolarMutex design, and this change can't do much about it. But for another, at least with GTK-based VCL backends, it also means that the current thread can start to execute VCL events at "unexpected" times from within this g_main_loop_run (e.g., paint events, as in the backtraces linked from tdf#124962). While handling of VCL events is necessary when a callback to ooo_mount_operation_ask_password happens and it actually pops up a dialog prompting the user for credentials, such handling of VCL events is completely unwanted when no such dialog is popped up (e.g., when the given server is unreachable anyway, as is the case in tdf#124962). So, to shrink the problematic window of time in which VCL events may get handled from within the gio MountOperation, use a dedicated GMainContext for the gio GMainLoop (so that it only handles events related to the mount operation), and only temporarily put back in place the original GMainContext during ooo_mount_operation_ask_password (so that VCL events will get handled as necessary when a dialog is actually popped up). Change-Id: Ie410f23778045b1adf98579bb34ce38d0f8f3320 Reviewed-on: https://gerrit.libreoffice.org/72026 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'ucb/source/ucp/gio/gio_mount.cxx')
-rw-r--r--ucb/source/ucp/gio/gio_mount.cxx26
1 files changed, 25 insertions, 1 deletions
diff --git a/ucb/source/ucp/gio/gio_mount.cxx b/ucb/source/ucp/gio/gio_mount.cxx
index d791fb3579be..be22b6d9bd3f 100644
--- a/ucb/source/ucp/gio/gio_mount.cxx
+++ b/ucb/source/ucp/gio/gio_mount.cxx
@@ -17,6 +17,10 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <sal/config.h>
+
+#include <utility>
+
#include "gio_mount.hxx"
#include <ucbhelper/simpleauthenticationrequest.hxx>
#include <string.h>
@@ -47,6 +51,7 @@ static void ooo_mount_operation_finalize (GObject *object)
free(mount_op->m_pPrevUsername);
if (mount_op->m_pPrevPassword)
free(mount_op->m_pPrevPassword);
+ mount_op->context.reset();
G_OBJECT_CLASS (ooo_mount_operation_parent_class)->finalize (object);
}
@@ -60,6 +65,23 @@ static void ooo_mount_operation_class_init (OOoMountOperationClass *klass)
mount_op_class->ask_password = ooo_mount_operation_ask_password;
}
+namespace {
+
+// Temporarily undo the g_main_context_push_thread_default done in the surrounding MountOperation
+// ctor (in ucb/source/ucp/gio/gio_content.cxx):
+struct GlibThreadDefaultMainContextScope {
+public:
+ GlibThreadDefaultMainContextScope(GMainContext * context): context_(context)
+ { g_main_context_push_thread_default(context_); }
+
+ ~GlibThreadDefaultMainContextScope() { g_main_context_pop_thread_default(context_); }
+
+private:
+ GMainContext * context_;
+};
+
+}
+
static void ooo_mount_operation_ask_password (GMountOperation *op,
const char * /*message*/, const char *default_user,
const char *default_domain, GAskPasswordFlags flags)
@@ -67,6 +89,7 @@ static void ooo_mount_operation_ask_password (GMountOperation *op,
css::uno::Reference< css::task::XInteractionHandler > xIH;
OOoMountOperation *pThis = reinterpret_cast<OOoMountOperation*>(op);
+ GlibThreadDefaultMainContextScope scope(pThis->context.get());
const css::uno::Reference< css::ucb::XCommandEnvironment > &xEnv = *(pThis->pEnv);
@@ -171,9 +194,10 @@ static void ooo_mount_operation_ask_password (GMountOperation *op,
g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED);
}
-GMountOperation *ooo_mount_operation_new(const css::uno::Reference< css::ucb::XCommandEnvironment >& rEnv)
+GMountOperation *ooo_mount_operation_new(ucb::ucp::gio::glib::MainContextRef && context, const css::uno::Reference< css::ucb::XCommandEnvironment >& rEnv)
{
OOoMountOperation *pRet = static_cast<OOoMountOperation*>(g_object_new (OOO_TYPE_MOUNT_OPERATION, nullptr));
+ pRet->context = std::move(context);
pRet->pEnv = &rEnv;
return &pRet->parent_instance;
}