SlotInformationStackLocation::SlotInformationStackLocation(SlotInformationStumpBase& stump, const void* pObj, size_t extent) : stump(stump), pObj(pObj), extent(extent), prior(*tss) { tss.reset(this); }
void SlotInformationStackLocation::RegisterSlot(DeferrableAutowiring* pDeferrable) { if(!tss.get()) // Nothing to do, this slot entry is missing return; if(tss->stump.bInitialized) // No reason to continue, stump already initialized return; if(!tss->Encloses(pDeferrable)) // Slot is extraneous, falling outside of the bounds of the original object--ignore return; tss->m_pCur = new SlotInformation( tss->m_pCur, pDeferrable->GetType(), reinterpret_cast<const unsigned char*>(pDeferrable) - reinterpret_cast<const unsigned char*>(tss->pObj), false ); }
TEST_F(AutowiringUtilitiesTest, ThreadSpecificPtr) { AutoCreateContext ctxt; CurrentContextPusher pshr(ctxt); AutoRequired<Thread1> thread1; AutoRequired<Thread2> thread2; s_thread_specific_int.reset(new int(5)); ctxt->Initiate(); std::this_thread::sleep_for(std::chrono::milliseconds(50)); EXPECT_EQ(5, *s_thread_specific_int); AutoCurrentContext()->SignalShutdown(true); }
SlotInformationStackLocation::~SlotInformationStackLocation(void) { // Replace the prior stack location, we were pushed tss.reset(&prior); const SlotInformation* p = nullptr; if (!stump.pHead.compare_exchange_strong(p, m_pCur, std::memory_order_acquire)) { // Failed the exchange, destroy std::unique_ptr<SlotInformation> prior; for (const auto* cur = m_pCur; cur; cur = cur->pFlink) prior.reset(m_pCur); } ///else // Exchange passed, the destination now owns this pointer // Unconditionally update to true, no CAS needed stump.bInitialized = true; }
TEST_F(AutowiringUtilitiesTest, ThreadSpecificPtr) { AutoCreateContext ctxt; CurrentContextPusher pshr(ctxt); AutoRequired<Thread1> thread1; AutoRequired<Thread2> thread2; s_thread_specific_int.reset(new int(5)); ctxt->Initiate(); auto limit = std::chrono::high_resolution_clock::now() + std::chrono::seconds(10); while(std::chrono::high_resolution_clock::now() < limit) if(5 == *s_thread_specific_int) return; FAIL() << "Thread specific pointer did not increment to the destination value in a timely fashion"; }
virtual void Run() { s_thread_specific_int.reset(new int(3)); std::this_thread::sleep_for(std::chrono::milliseconds(50)); EXPECT_EQ(3, *s_thread_specific_int); }
SlotInformationStackLocation* SlotInformationStackLocation::CurrentStackLocation(void) { return tss.get(); }