*/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.
This commit is contained in:
Max Kellermann
2014-02-06 22:19:59 +01:00
parent a7989077ab
commit c8f0c7e9ed
7 changed files with 86 additions and 1 deletions

View File

@@ -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");