Skip to content

Commit

Permalink
Merge pull request #899 from leapmotion/bug-deferredteardown
Browse files Browse the repository at this point in the history
Correct invalid deferred destruction
  • Loading branch information
ajohnston33 committed Apr 18, 2016
2 parents eb3d0e9 + 5bb1b81 commit a1de71f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/autowiring/CoreContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,10 @@ class CoreContext:
return memo.m_value.template as<T>();
}

// Need the memo for the actual type at this point, if we don't hold this down then this
// entry might not get constructed.
auto& memo = FindByType(auto_id_t<typename CreationRules::TActual>{}, true);

// We must make ourselves current for the remainder of this call:
CurrentContextPusher pshr(shared_from_this());
std::shared_ptr<typename CreationRules::TActual> retVal(
Expand All @@ -607,7 +611,6 @@ class CoreContext:
// we will simply eat this exception, and handle it silently by returning the type that
// someone else has already attempted to construct, as per the documented behavior of
// Construct.
auto& memo = FindByType(auto_id_t<typename CreationRules::TActual>{}, true);
retVal = memo.m_value.template as<typename CreationRules::TActual>();
}

Expand Down
50 changes: 50 additions & 0 deletions src/autowiring/test/CoreContextTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -636,3 +636,53 @@ TEST_F(CoreContextTest, AwaitTimed) {

injector.join();
}

namespace {
class HoldsMutexAndCount {
public:
volatile int hitCount = 0;
int initCount = 0;
int instanceCount = 0;
std::mutex lk;
};

class DelaysWithNwa {
public:
DelaysWithNwa(void) {
hmac->hitCount++;
std::lock_guard<std::mutex>{ hmac->lk };

hmac->initCount++;
hmac->instanceCount++;
}

virtual ~DelaysWithNwa(void) {
hmac->instanceCount--;
}

AutoRequired<HoldsMutexAndCount> hmac;
};
}

TEST_F(CoreContextTest, SimultaneousMultiInject) {
AutoCreateContext ctxt;
AutoRequired<HoldsMutexAndCount> hmac{ ctxt };

std::unique_lock<std::mutex> lk{ hmac->lk };
std::thread a([ctxt] { ctxt->Inject<DelaysWithNwa>(); });
std::thread b([ctxt] { ctxt->Inject<DelaysWithNwa>(); });

// Poor man's barrier
while (hmac->hitCount != 2)
std::this_thread::yield();
lk.unlock();

a.join();
b.join();

// Two initializations should have taken place due to the barrier
ASSERT_EQ(2, hmac->initCount);

// Only one of those two instances should still be around
ASSERT_EQ(1, hmac->instanceCount);
}

0 comments on commit a1de71f

Please sign in to comment.