aboutsummaryrefslogtreecommitdiffstats
path: root/src/storage
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-02-06 22:19:59 +0100
committerMax Kellermann <max@duempel.org>2014-02-06 22:19:59 +0100
commitc8f0c7e9ede1cfef49ea9d4b71b6b56b4ae87141 (patch)
tree85adef73380393703c71202f20601d99df135b00 /src/storage
parenta7989077abe2b862b131b7573380a82f889bad95 (diff)
downloadmpd-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.cxx16
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");