Introduce a mutex for OpenBlockList
This commit is contained in:
parent
9b5ad835db
commit
41600c13f7
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user