summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2011-10-08 07:40:01 (GMT)
committerRemko Tronçon <git@el-tramo.be>2011-10-08 07:40:01 (GMT)
commit2c6f1075474f6b8086cc6abf7978aee9421761c8 (patch)
tree33dede68126fa3f9355406de7067d63499bd7775
parent3fafb8bb9387d859bc187c23db6efac90c8683d4 (diff)
downloadswift-2c6f1075474f6b8086cc6abf7978aee9421761c8.zip
swift-2c6f1075474f6b8086cc6abf7978aee9421761c8.tar.bz2
Protect JID cache access with mutex.
The overhead appears to be neglectible. Using TSS had a similar overhead, with the disadvantages that it uses more storage (one cache per thread vs one cache), has less cache reuse, and that Windows/MSVC doesn't support automatic TSS cleanup, so it requires manual cleanup work (which is non-trivial). Note that the mutex approach may yield more overhead in multi-threaded applications (in case of contention). Currently, the mutex also locks during the whole nameprep sequence, which is not strictly necessary.
-rw-r--r--Swiften/JID/JID.cpp8
1 files changed, 8 insertions, 0 deletions
diff --git a/Swiften/JID/JID.cpp b/Swiften/JID/JID.cpp
index 66d6ff6..9b47ef7 100644
--- a/Swiften/JID/JID.cpp
+++ b/Swiften/JID/JID.cpp
@@ -12,6 +12,7 @@
#include <string>
#ifdef SWIFTEN_CACHE_JID_PREP
+#include <boost/thread/mutex.hpp>
#include <boost/unordered_map.hpp>
#endif
#include <boost/assign/list_of.hpp>
@@ -29,6 +30,7 @@ using namespace Swift;
#ifdef SWIFTEN_CACHE_JID_PREP
typedef boost::unordered_map<std::string, std::string> PrepCache;
+static boost::mutex namePrepCacheMutex;
static PrepCache nodePrepCache;
static PrepCache domainPrepCache;
static PrepCache resourcePrepCache;
@@ -154,12 +156,18 @@ void JID::initializeFromString(const std::string& jid) {
void JID::nameprepAndSetComponents(const std::string& node, const std::string& domain, const std::string& resource) {
+ if (domain.empty()) {
+ valid_ = false;
+ return;
+ }
try {
#ifndef SWIFTEN_CACHE_JID_PREP
node_ = StringPrep::getPrepared(node, StringPrep::NamePrep);
domain_ = StringPrep::getPrepared(domain, StringPrep::XMPPNodePrep);
resource_ = StringPrep::getPrepared(resource, StringPrep::XMPPResourcePrep);
#else
+ boost::mutex::scoped_lock lock(namePrepCacheMutex);
+
std::pair<PrepCache::iterator, bool> r;
r = nodePrepCache.insert(std::make_pair(node, std::string()));