Introduce a mutex for OpenBlockList

This commit is contained in:
Sebastian Meßmer 2015-03-29 08:36:09 -04:00
parent 9b5ad835db
commit 41600c13f7
2 changed files with 10 additions and 1 deletions

View File

@ -22,16 +22,18 @@ OpenBlockList::~OpenBlockList() {
} }
unique_ptr<Block> OpenBlockList::insert(unique_ptr<Block> block) { unique_ptr<Block> OpenBlockList::insert(unique_ptr<Block> block) {
lock_guard<mutex> lock(_mutex);
auto insertResult = _openBlocks.insert(block->key()); auto insertResult = _openBlocks.insert(block->key());
assert(insertResult.second == true); assert(insertResult.second == true);
return make_unique<OpenBlock>(std::move(block), this); return make_unique<OpenBlock>(std::move(block), this);
} }
unique_ptr<Block> OpenBlockList::acquire(const Key &key, function<unique_ptr<Block> ()> loader) { unique_ptr<Block> OpenBlockList::acquire(const Key &key, function<unique_ptr<Block> ()> loader) {
//TODO Think it through, whether we really don't need any locks here. unique_lock<mutex> lock(_mutex);
auto insertResult = _openBlocks.insert(key); auto insertResult = _openBlocks.insert(key);
auto blockWasNotOpenYet = insertResult.second; auto blockWasNotOpenYet = insertResult.second;
if (blockWasNotOpenYet) { if (blockWasNotOpenYet) {
lock.unlock();
auto block = loader(); auto block = loader();
if (block.get() == nullptr) { if (block.get() == nullptr) {
return nullptr; return nullptr;
@ -39,6 +41,7 @@ unique_ptr<Block> OpenBlockList::acquire(const Key &key, function<unique_ptr<Blo
return make_unique<OpenBlock>(std::move(block), this); return make_unique<OpenBlock>(std::move(block), this);
} else { } else {
auto blockFuture = _addPromiseForBlock(key); auto blockFuture = _addPromiseForBlock(key);
lock.unlock();
return blockFuture.get(); return blockFuture.get();
} }
} }
@ -50,6 +53,7 @@ future<unique_ptr<Block>> OpenBlockList::_addPromiseForBlock(const Key &key) {
} }
void OpenBlockList::release(unique_ptr<Block> block) { void OpenBlockList::release(unique_ptr<Block> block) {
lock_guard<mutex> lock(_mutex);
auto foundWantedBlock = _wantedBlocks.find(block->key()); auto foundWantedBlock = _wantedBlocks.find(block->key());
if (foundWantedBlock != _wantedBlocks.end()) { if (foundWantedBlock != _wantedBlocks.end()) {
foundWantedBlock->second.set_value(std::move(block)); foundWantedBlock->second.set_value(std::move(block));
@ -63,9 +67,11 @@ void OpenBlockList::release(unique_ptr<Block> block) {
} }
void OpenBlockList::close(unique_ptr<Block> block, function<void (unique_ptr<Block>)> onClose) { void OpenBlockList::close(unique_ptr<Block> block, function<void (unique_ptr<Block>)> onClose) {
unique_lock<mutex> lock(_mutex);
auto insertResult = _blocksToClose.emplace(block->key(), promise<unique_ptr<Block>>()); auto insertResult = _blocksToClose.emplace(block->key(), promise<unique_ptr<Block>>());
assert(insertResult.second == true); assert(insertResult.second == true);
block.reset(); block.reset();
lock.unlock();
auto closedBlock = insertResult.first->second.get_future().get(); auto closedBlock = insertResult.first->second.get_future().get();
onClose(std::move(closedBlock)); onClose(std::move(closedBlock));
} }

View File

@ -6,6 +6,7 @@
#include <map> #include <map>
#include <vector> #include <vector>
#include <functional> #include <functional>
#include <mutex>
#include "../../utils/Key.h" #include "../../utils/Key.h"
#include <future> #include <future>
@ -29,6 +30,8 @@ private:
std::set<Key> _openBlocks; std::set<Key> _openBlocks;
std::map<Key, std::promise<std::unique_ptr<Block>>> _wantedBlocks; std::map<Key, std::promise<std::unique_ptr<Block>>> _wantedBlocks;
std::map<Key, std::promise<std::unique_ptr<Block>>> _blocksToClose; std::map<Key, std::promise<std::unique_ptr<Block>>> _blocksToClose;
//TODO Check whether we need this mutex or whether we can write it threadsafe without a mutex
mutable std::mutex _mutex;
std::future<std::unique_ptr<Block>> _addPromiseForBlock(const Key &key); std::future<std::unique_ptr<Block>> _addPromiseForBlock(const Key &key);
}; };