diff options
author | Max Kellermann <max@duempel.org> | 2014-02-06 22:19:59 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-02-06 22:19:59 +0100 |
commit | c8f0c7e9ede1cfef49ea9d4b71b6b56b4ae87141 (patch) | |
tree | 85adef73380393703c71202f20601d99df135b00 /src/storage | |
parent | a7989077abe2b862b131b7573380a82f889bad95 (diff) | |
download | mpd-c8f0c7e9ede1cfef49ea9d4b71b6b56b4ae87141.tar.gz mpd-c8f0c7e9ede1cfef49ea9d4b71b6b56b4ae87141.tar.xz mpd-c8f0c7e9ede1cfef49ea9d4b71b6b56b4ae87141.zip |
*/smbclient: protect all libsmbclient calls with a mutex
libsmbclient is not thread-safe nor reentrant. We must protect all
function calls with a global mutex, unfortunately.
Diffstat (limited to 'src/storage')
-rw-r--r-- | src/storage/plugins/SmbclientStorage.cxx | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/storage/plugins/SmbclientStorage.cxx b/src/storage/plugins/SmbclientStorage.cxx index 1ba9e9e5f..8dafff082 100644 --- a/src/storage/plugins/SmbclientStorage.cxx +++ b/src/storage/plugins/SmbclientStorage.cxx @@ -22,7 +22,9 @@ #include "storage/StorageInterface.hxx" #include "storage/FileInfo.hxx" #include "lib/smbclient/Init.hxx" +#include "lib/smbclient/Mutex.hxx" #include "util/Error.hxx" +#include "thread/Mutex.hxx" #include <libsmbclient.h> @@ -54,7 +56,9 @@ public: :base(_base), ctx(_ctx) {} virtual ~SmbclientStorage() { + smbclient_mutex.lock(); smbc_free_context(ctx, 1); + smbclient_mutex.unlock(); } /* virtual methods from class Storage */ @@ -82,7 +86,10 @@ static bool GetInfo(const char *path, FileInfo &info, Error &error) { struct stat st; - if (smbc_stat(path, &st) < 0) { + smbclient_mutex.lock(); + bool success = smbc_stat(path, &st) == 0; + smbclient_mutex.unlock(); + if (!success) { error.SetErrno(); return false; } @@ -113,7 +120,9 @@ StorageDirectoryReader * SmbclientStorage::OpenDirectory(const char *uri_utf8, Error &error) { std::string mapped = MapUTF8(uri_utf8); + smbclient_mutex.lock(); int handle = smbc_opendir(mapped.c_str()); + smbclient_mutex.unlock(); if (handle < 0) { error.SetErrno(); return nullptr; @@ -133,12 +142,16 @@ SkipNameFS(const char *name) SmbclientDirectoryReader::~SmbclientDirectoryReader() { + smbclient_mutex.lock(); smbc_close(handle); + smbclient_mutex.unlock(); } const char * SmbclientDirectoryReader::Read() { + const ScopeLock protect(smbclient_mutex); + struct smbc_dirent *e; while ((e = smbc_readdir(handle)) != nullptr) { name = e->name; @@ -163,6 +176,7 @@ CreateSmbclientStorage(const char *base, Error &error) if (!SmbclientInit(error)) return nullptr; + const ScopeLock protect(smbclient_mutex); SMBCCTX *ctx = smbc_new_context(); if (ctx == nullptr) { error.SetErrno("smbc_new_context() failed"); |