Commit bb3f487e authored by Max Kellermann's avatar Max Kellermann

lib/smbclient/Context: add global Mutex for smbc_{new,free}_context()

Preparing to replace `smbclient_mutex`, for finer-grained locking.
parent 7d97d0ae
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include <string.h> #include <string.h>
Mutex SmbclientContext::global_mutex;
static void static void
mpd_smbc_get_auth_data([[maybe_unused]] const char *srv, mpd_smbc_get_auth_data([[maybe_unused]] const char *srv,
[[maybe_unused]] const char *shr, [[maybe_unused]] const char *shr,
...@@ -40,7 +42,13 @@ mpd_smbc_get_auth_data([[maybe_unused]] const char *srv, ...@@ -40,7 +42,13 @@ mpd_smbc_get_auth_data([[maybe_unused]] const char *srv,
SmbclientContext SmbclientContext
SmbclientContext::New() SmbclientContext::New()
{ {
SMBCCTX *ctx = smbc_new_context(); SMBCCTX *ctx;
{
const std::lock_guard<Mutex> protect(global_mutex);
ctx = smbc_new_context();
}
if (ctx == nullptr) if (ctx == nullptr)
throw MakeErrno("smbc_new_context() failed"); throw MakeErrno("smbc_new_context() failed");
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#ifndef MPD_SMBCLIENT_CONTEXT_HXX #ifndef MPD_SMBCLIENT_CONTEXT_HXX
#define MPD_SMBCLIENT_CONTEXT_HXX #define MPD_SMBCLIENT_CONTEXT_HXX
#include "thread/Mutex.hxx"
#include <libsmbclient.h> #include <libsmbclient.h>
#include <utility> #include <utility>
...@@ -28,6 +30,14 @@ ...@@ -28,6 +30,14 @@
* Wrapper for `SMBCCTX*`. * Wrapper for `SMBCCTX*`.
*/ */
class SmbclientContext { 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; SMBCCTX *ctx = nullptr;
explicit SmbclientContext(SMBCCTX *_ctx) noexcept explicit SmbclientContext(SMBCCTX *_ctx) noexcept
...@@ -37,9 +47,11 @@ public: ...@@ -37,9 +47,11 @@ public:
SmbclientContext() = default; SmbclientContext() = default;
~SmbclientContext() noexcept { ~SmbclientContext() noexcept {
if (ctx != nullptr) if (ctx != nullptr) {
const std::lock_guard<Mutex> protect(global_mutex);
smbc_free_context(ctx, 1); smbc_free_context(ctx, 1);
} }
}
SmbclientContext(SmbclientContext &&src) noexcept SmbclientContext(SmbclientContext &&src) noexcept
:ctx(std::exchange(src.ctx, nullptr)) {} :ctx(std::exchange(src.ctx, nullptr)) {}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment