diff --git a/src/lib/smbclient/Context.cxx b/src/lib/smbclient/Context.cxx index f61a80042..1a4239dc1 100644 --- a/src/lib/smbclient/Context.cxx +++ b/src/lib/smbclient/Context.cxx @@ -24,6 +24,8 @@ #include +Mutex SmbclientContext::global_mutex; + static void mpd_smbc_get_auth_data([[maybe_unused]] const char *srv, [[maybe_unused]] const char *shr, @@ -40,7 +42,13 @@ mpd_smbc_get_auth_data([[maybe_unused]] const char *srv, SmbclientContext SmbclientContext::New() { - SMBCCTX *ctx = smbc_new_context(); + SMBCCTX *ctx; + + { + const std::lock_guard protect(global_mutex); + ctx = smbc_new_context(); + } + if (ctx == nullptr) throw MakeErrno("smbc_new_context() failed"); diff --git a/src/lib/smbclient/Context.hxx b/src/lib/smbclient/Context.hxx index c892ddcc7..9c8d255e8 100644 --- a/src/lib/smbclient/Context.hxx +++ b/src/lib/smbclient/Context.hxx @@ -20,6 +20,8 @@ #ifndef MPD_SMBCLIENT_CONTEXT_HXX #define MPD_SMBCLIENT_CONTEXT_HXX +#include "thread/Mutex.hxx" + #include #include @@ -28,6 +30,14 @@ * Wrapper for `SMBCCTX*`. */ class SmbclientContext { + /** + * This mutex protects the libsmbclient functions + * smbc_new_context() and smbc_free_context() which need to be + * serialized. We need to do this because we can't use + * smbc_thread_posix(), which is not exported by libsmbclient. + */ + static Mutex global_mutex; + SMBCCTX *ctx = nullptr; explicit SmbclientContext(SMBCCTX *_ctx) noexcept @@ -37,8 +47,10 @@ public: SmbclientContext() = default; ~SmbclientContext() noexcept { - if (ctx != nullptr) + if (ctx != nullptr) { + const std::lock_guard protect(global_mutex); smbc_free_context(ctx, 1); + } } SmbclientContext(SmbclientContext &&src) noexcept