Fix race condition in IArchString

Even though the calls to C functions are protected with a mutex, the
initialization and destruction of the mutex itself had race conditions.
This commit is contained in:
Povilas Kanapickas 2019-08-17 16:40:25 +03:00
parent 83d0639230
commit b0e415de03
1 changed files with 7 additions and 19 deletions

View File

@ -24,7 +24,9 @@
#include <cstring> #include <cstring>
#include <cstdlib> #include <cstdlib>
static ArchMutex s_mutex = NULL; #include <mutex>
std::mutex s_mutex;
// //
// use C library non-reentrant multibyte conversion with mutex // use C library non-reentrant multibyte conversion with mutex
@ -32,16 +34,14 @@ static ArchMutex s_mutex = NULL;
IArchString::~IArchString() IArchString::~IArchString()
{ {
if (s_mutex != NULL) {
ARCH->closeMutex(s_mutex);
s_mutex = NULL;
}
} }
int int
IArchString::convStringWCToMB(char* dst, IArchString::convStringWCToMB(char* dst,
const wchar_t* src, UInt32 n, bool* errors) const wchar_t* src, UInt32 n, bool* errors)
{ {
std::lock_guard<std::mutex> lock(s_mutex);
ptrdiff_t len = 0; ptrdiff_t len = 0;
bool dummyErrors; bool dummyErrors;
@ -49,12 +49,6 @@ IArchString::convStringWCToMB(char* dst,
errors = &dummyErrors; errors = &dummyErrors;
} }
if (s_mutex == NULL) {
s_mutex = ARCH->newMutex();
}
ARCH->lockMutex(s_mutex);
if (dst == NULL) { if (dst == NULL) {
char dummy[MB_LEN_MAX]; char dummy[MB_LEN_MAX];
for (const wchar_t* scan = src; n > 0; ++scan, --n) { for (const wchar_t* scan = src; n > 0; ++scan, --n) {
@ -89,7 +83,6 @@ IArchString::convStringWCToMB(char* dst,
} }
len = dst - dst0; len = dst - dst0;
} }
ARCH->unlockMutex(s_mutex);
return (int)len; return (int)len;
} }
@ -98,6 +91,8 @@ int
IArchString::convStringMBToWC(wchar_t* dst, IArchString::convStringMBToWC(wchar_t* dst,
const char* src, UInt32 n_param, bool* errors) const char* src, UInt32 n_param, bool* errors)
{ {
std::lock_guard<std::mutex> lock(s_mutex);
ptrdiff_t n = (ptrdiff_t)n_param; // fix compiler warning ptrdiff_t n = (ptrdiff_t)n_param; // fix compiler warning
ptrdiff_t len = 0; ptrdiff_t len = 0;
wchar_t dummy; wchar_t dummy;
@ -107,12 +102,6 @@ IArchString::convStringMBToWC(wchar_t* dst,
errors = &dummyErrors; errors = &dummyErrors;
} }
if (s_mutex == NULL) {
s_mutex = ARCH->newMutex();
}
ARCH->lockMutex(s_mutex);
if (dst == NULL) { if (dst == NULL) {
for (const char* scan = src; n > 0; ) { for (const char* scan = src; n > 0; ) {
ptrdiff_t mblen = mbtowc(&dummy, scan, n); ptrdiff_t mblen = mbtowc(&dummy, scan, n);
@ -184,7 +173,6 @@ IArchString::convStringMBToWC(wchar_t* dst,
} }
len = dst - dst0; len = dst - dst0;
} }
ARCH->unlockMutex(s_mutex);
return (int)len; return (int)len;
} }