Commit 2d1c9a53 authored by Kenton Varda's avatar Kenton Varda

Remove a bunch of mutexes.

parent bf7af0b6
...@@ -161,7 +161,7 @@ private: ...@@ -161,7 +161,7 @@ private:
} }
private: private:
mutable kj::Vector<kj::String> caps; kj::Vector<kj::String> caps;
}; };
}; };
......
This diff is collapsed.
...@@ -560,25 +560,22 @@ void TransformPromiseNodeBase::getDepResult(ExceptionOrValue& output) { ...@@ -560,25 +560,22 @@ void TransformPromiseNodeBase::getDepResult(ExceptionOrValue& output) {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
ForkBranchBase::ForkBranchBase(Own<ForkHubBase>&& hubParam): hub(kj::mv(hubParam)) { ForkBranchBase::ForkBranchBase(Own<ForkHubBase>&& hubParam): hub(kj::mv(hubParam)) {
auto lock = hub->branchList.lockExclusive(); if (hub->tailBranch == nullptr) {
if (lock->lastPtr == nullptr) {
onReadyEvent.arm(); onReadyEvent.arm();
} else { } else {
// Insert into hub's linked list of branches. // Insert into hub's linked list of branches.
prevPtr = lock->lastPtr; prevPtr = hub->tailBranch;
*prevPtr = this; *prevPtr = this;
next = nullptr; next = nullptr;
lock->lastPtr = &next; hub->tailBranch = &next;
} }
} }
ForkBranchBase::~ForkBranchBase() noexcept(false) { ForkBranchBase::~ForkBranchBase() noexcept(false) {
if (prevPtr != nullptr) { if (prevPtr != nullptr) {
// Remove from hub's linked list of branches. // Remove from hub's linked list of branches.
auto lock = hub->branchList.lockExclusive();
*prevPtr = next; *prevPtr = next;
(next == nullptr ? lock->lastPtr : next->prevPtr) = prevPtr; (next == nullptr ? hub->tailBranch : next->prevPtr) = prevPtr;
} }
} }
...@@ -618,16 +615,15 @@ Maybe<Own<EventLoop::Event>> ForkHubBase::fire() { ...@@ -618,16 +615,15 @@ Maybe<Own<EventLoop::Event>> ForkHubBase::fire() {
resultRef.addException(kj::mv(*exception)); resultRef.addException(kj::mv(*exception));
} }
auto lock = branchList.lockExclusive(); for (auto branch = headBranch; branch != nullptr; branch = branch->next) {
for (auto branch = lock->first; branch != nullptr; branch = branch->next) {
branch->hubReady(); branch->hubReady();
*branch->prevPtr = nullptr; *branch->prevPtr = nullptr;
branch->prevPtr = nullptr; branch->prevPtr = nullptr;
} }
*lock->lastPtr = nullptr; *tailBranch = nullptr;
// Indicate that the list is no longer active. // Indicate that the list is no longer active.
lock->lastPtr = nullptr; tailBranch = nullptr;
return nullptr; return nullptr;
} }
......
...@@ -1108,16 +1108,12 @@ public: ...@@ -1108,16 +1108,12 @@ public:
inline ExceptionOrValue& getResultRef() { return resultRef; } inline ExceptionOrValue& getResultRef() { return resultRef; }
private: private:
struct BranchList {
ForkBranchBase* first = nullptr;
ForkBranchBase** lastPtr = &first;
};
Own<PromiseNode> inner; Own<PromiseNode> inner;
ExceptionOrValue& resultRef; ExceptionOrValue& resultRef;
MutexGuarded<BranchList> branchList; ForkBranchBase* headBranch = nullptr;
// Becomes null once the inner promise is ready and all branches have been notified. ForkBranchBase** tailBranch = &headBranch;
// Tail becomes null once the inner promise is ready and all branches have been notified.
Maybe<Own<Event>> fire() override; Maybe<Own<Event>> fire() override;
_::PromiseNode* getInnerForTrace() override; _::PromiseNode* getInnerForTrace() override;
...@@ -1451,61 +1447,54 @@ public: ...@@ -1451,61 +1447,54 @@ public:
} }
void fulfill(FixVoid<T>&& value) override { void fulfill(FixVoid<T>&& value) override {
auto lock = inner.lockExclusive(); if (inner != nullptr) {
if (*lock != nullptr) { inner->fulfill(kj::mv(value));
(*lock)->fulfill(kj::mv(value));
} }
} }
void reject(Exception&& exception) override { void reject(Exception&& exception) override {
auto lock = inner.lockExclusive(); if (inner != nullptr) {
if (*lock != nullptr) { inner->reject(kj::mv(exception));
(*lock)->reject(kj::mv(exception));
} }
} }
bool isWaiting() override { bool isWaiting() override {
auto lock = inner.lockExclusive(); return inner != nullptr && inner->isWaiting();
return *lock != nullptr && (*lock)->isWaiting();
} }
void attach(PromiseFulfiller<T>& newInner) { void attach(PromiseFulfiller<T>& newInner) {
inner.getWithoutLock() = &newInner; inner = &newInner;
} }
void detach(PromiseFulfiller<T>& from) { void detach(PromiseFulfiller<T>& from) {
auto lock = inner.lockExclusive(); if (inner == nullptr) {
if (*lock == nullptr) {
// Already disposed. // Already disposed.
lock.release();
delete this; delete this;
} else { } else {
KJ_IREQUIRE(*lock == &from); KJ_IREQUIRE(inner == &from);
*lock = nullptr; inner = nullptr;
} }
} }
private: private:
MutexGuarded<PromiseFulfiller<T>*> inner; mutable PromiseFulfiller<T>* inner;
WeakFulfiller(): inner(nullptr) {} WeakFulfiller(): inner(nullptr) {}
void disposeImpl(void* pointer) const override { void disposeImpl(void* pointer) const override {
// TODO(perf): Factor some of this out so it isn't regenerated for every fulfiller type? // TODO(perf): Factor some of this out so it isn't regenerated for every fulfiller type?
auto lock = inner.lockExclusive(); if (inner == nullptr) {
if (*lock == nullptr) {
// Already detached. // Already detached.
lock.release();
delete this; delete this;
} else { } else {
if ((*lock)->isWaiting()) { if (inner->isWaiting()) {
(*lock)->reject(kj::Exception( inner->reject(kj::Exception(
kj::Exception::Nature::LOCAL_BUG, kj::Exception::Durability::PERMANENT, kj::Exception::Nature::LOCAL_BUG, kj::Exception::Durability::PERMANENT,
__FILE__, __LINE__, __FILE__, __LINE__,
kj::heapString("PromiseFulfiller was destroyed without fulfilling the promise."))); kj::heapString("PromiseFulfiller was destroyed without fulfilling the promise.")));
} }
*lock = nullptr; inner = nullptr;
} }
} }
}; };
......
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