Commit 7f17b7bd authored by Kenton Varda's avatar Kenton Varda

Make sure reading far pointers is thread-safe.

parent 3c7505d6
......@@ -63,12 +63,10 @@ SegmentReader* ReaderArena::tryGetSegment(SegmentId id) {
}
}
// TODO(someday): Lock a mutex so that reading is thread-safe. Take a reader lock during the
// first lookup, unlock it before calling getSegment(), then take a writer lock to update the
// map. Bleh, lazy initialization is sad.
auto lock = moreSegments.lockExclusive();
SegmentMap* segments = nullptr;
KJ_IF_MAYBE(s, moreSegments) {
KJ_IF_MAYBE(s, *lock) {
auto iter = s->find(id.value);
if (iter != s->end()) {
return iter->second.get();
......@@ -81,11 +79,11 @@ SegmentReader* ReaderArena::tryGetSegment(SegmentId id) {
return nullptr;
}
if (moreSegments == nullptr) {
if (*lock == nullptr) {
// OK, the segment exists, so allocate the map.
auto s = kj::heap<SegmentMap>();
segments = s;
moreSegments = mv(s);
*lock = mv(s);
}
auto segment = kj::heap<SegmentReader>(this, id, newSegment, &readLimiter);
......
......@@ -171,7 +171,7 @@ private:
SegmentReader segment0;
typedef std::unordered_map<uint, kj::Own<SegmentReader>> SegmentMap;
kj::Maybe<kj::Own<SegmentMap>> moreSegments;
kj::MutexGuarded<kj::Maybe<kj::Own<SegmentMap>>> moreSegments;
};
class BuilderArena final: public Arena {
......
......@@ -124,7 +124,7 @@ private:
// because we don't want clients to have to #include arena.h, which itself includes a bunch of
// big STL headers. We don't use a pointer to a ReaderArena because that would require an
// extra malloc on every message which could be expensive when processing small messages.
void* arenaSpace[15];
void* arenaSpace[15 + sizeof(kj::MutexGuarded<void*>) / sizeof(void*)];
bool allocatedArena;
_::ReaderArena* arena() { return reinterpret_cast<_::ReaderArena*>(arenaSpace); }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment