/
SlotInformation.cpp
64 lines (53 loc) · 1.9 KB
/
SlotInformation.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include "SlotInformation.h"
#include "AutowirableSlot.h"
#include "thread_specific_ptr.h"
#include MEMORY_HEADER
using namespace autowiring;
// Special file-level allocation with a no-op dtor, because all stack locations are stack-allocated
static autowiring::thread_specific_ptr<SlotInformationStackLocation> tss([](void*) {});
SlotInformationStackLocation::SlotInformationStackLocation(SlotInformationStumpBase& stump, const void* pObj, size_t extent) :
stump(stump),
pObj(pObj),
extent(extent),
prior(*tss)
{
tss.reset(this);
}
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;
}
SlotInformationStackLocation* SlotInformationStackLocation::CurrentStackLocation(void) {
return tss.get();
}
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
);
}