diff options
author | Remko Tronçon <git@el-tramo.be> | 2011-10-08 07:40:01 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2011-10-08 07:40:01 (GMT) |
commit | 2c6f1075474f6b8086cc6abf7978aee9421761c8 (patch) | |
tree | 33dede68126fa3f9355406de7067d63499bd7775 | |
parent | 3fafb8bb9387d859bc187c23db6efac90c8683d4 (diff) | |
download | swift-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.cpp | 8 |
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())); |