aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2009-12-08 10:21:33 +0000
committerVincent Richard <[email protected]>2009-12-08 10:21:33 +0000
commit7a6dcdf385d8641afe3dea66a0822c43151b67d4 (patch)
treefec6fa91b47996af25aceb15c7765e6f819a9e33
parentFixed not exception-safe constructor, which could lead to possible memory lea... (diff)
downloadvmime-7a6dcdf385d8641afe3dea66a0822c43151b67d4.tar.gz
vmime-7a6dcdf385d8641afe3dea66a0822c43151b67d4.zip
Fixed non thread-safe getLocalCharset() function (thanks to Bartek Szurgot).
-rw-r--r--src/platforms/posix/posixHandler.cpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/platforms/posix/posixHandler.cpp b/src/platforms/posix/posixHandler.cpp
index 104bc404..2c113072 100644
--- a/src/platforms/posix/posixHandler.cpp
+++ b/src/platforms/posix/posixHandler.cpp
@@ -36,6 +36,11 @@
#include <netdb.h>
#include <string.h>
+#include <cassert>
+
+#if VMIME_HAVE_PTHREAD
+# include <pthread.h>
+#endif // VMIME_HAVE_PTHREAD
/*
#ifdef _POSIX_PRIORITY_SCHEDULING
@@ -44,6 +49,43 @@
*/
+#if VMIME_HAVE_PTHREAD
+
+namespace
+{
+ // This construction ensures mutex will be initialized in compile-time
+ // and will be available any time in the runtime.
+ pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+ // Helper lock, to be exception safe all the time.
+ class PLockHelper
+ {
+ public:
+
+ PLockHelper()
+ {
+ if (pthread_mutex_lock(&g_mutex) != 0)
+ assert(!"unable to lock mutex - thread safety's void");
+ }
+
+ ~PLockHelper()
+ {
+ if (pthread_mutex_unlock(&g_mutex) != 0)
+ assert(!"unable to unlock mutex - application's dead...");
+ }
+
+ private:
+
+ // Object cannot be copied
+ PLockHelper(const PLockHelper&);
+ const PLockHelper& operator=(const PLockHelper&);
+ };
+
+} // unnamed namespace
+
+#endif // VMIME_HAVE_PTHREAD
+
+
namespace vmime {
namespace platforms {
namespace posix {
@@ -109,6 +151,8 @@ const vmime::datetime posixHandler::getCurrentLocalTime() const
const vmime::charset posixHandler::getLocaleCharset() const
{
+ const PLockHelper lock;
+
const char* prevLocale = ::setlocale(LC_ALL, "");
vmime::charset ch(::nl_langinfo(CODESET));
::setlocale(LC_ALL, prevLocale);