summaryrefslogtreecommitdiff
path: root/src/mongo/util/concurrency/mapsf.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/util/concurrency/mapsf.h')
-rw-r--r--src/mongo/util/concurrency/mapsf.h59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/mongo/util/concurrency/mapsf.h b/src/mongo/util/concurrency/mapsf.h
new file mode 100644
index 00000000000..e0ddd0ac701
--- /dev/null
+++ b/src/mongo/util/concurrency/mapsf.h
@@ -0,0 +1,59 @@
+#pragma once
+
+namespace mongo {
+
+ /** Thread safe map.
+ Be careful not to use this too much or it could make things slow;
+ if not a hot code path no problem.
+
+ Examples:
+
+ mapsf<int,int> mp;
+
+ int x = mp.get();
+
+ map<int,int> two;
+ mp.swap(two);
+
+ {
+ mapsf<int,int>::ref r(mp);
+ r[9] = 1;
+ map<int,int>::iterator i = r.r.begin();
+ }
+
+ */
+ template< class K, class V >
+ struct mapsf : boost::noncopyable {
+ SimpleMutex m;
+ map<K,V> val;
+ friend struct ref;
+ public:
+ mapsf() : m("mapsf") { }
+ void swap(map<K,V>& rhs) {
+ SimpleMutex::scoped_lock lk(m);
+ val.swap(rhs);
+ }
+ bool empty() {
+ SimpleMutex::scoped_lock lk(m);
+ return val.empty();
+ }
+ // safe as we pass by value:
+ V get(K k) {
+ SimpleMutex::scoped_lock lk(m);
+ typename map<K,V>::iterator i = val.find(k);
+ if( i == val.end() )
+ return V();
+ return i->second;
+ }
+ // think about deadlocks when using ref. the other methods
+ // above will always be safe as they are "leaf" operations.
+ struct ref {
+ SimpleMutex::scoped_lock lk;
+ public:
+ map<K,V> &r;
+ ref(mapsf<K,V> &m) : lk(m.m), r(m.val) { }
+ V& operator[](const K& k) { return r[k]; }
+ };
+ };
+
+}