Skip to content

Commit 826b6f0

Browse files
Stop using std::map since it races with the finalizer during shutdown. (#38375)
1 parent 49823c6 commit 826b6f0

File tree

1 file changed

+68
-7
lines changed

1 file changed

+68
-7
lines changed

src/coreclr/tests/src/Interop/COM/NativeClients/Events/EventTests.cpp

+68-7
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,89 @@
1616
#define THROW_IF_FAILED(exp) { hr = exp; if (FAILED(hr)) { ::printf("FAILURE: 0x%08x = %s\n", hr, #exp); throw hr; } }
1717
#define THROW_FAIL_IF_FALSE(exp) { if (!(exp)) { ::printf("FALSE: %s\n", #exp); throw E_FAIL; } }
1818

19-
#include <map>
2019
#include <string>
2120

2221
namespace
2322
{
23+
class DispIDToStringMap
24+
{
25+
struct Pair
26+
{
27+
DISPID id;
28+
WCHAR value[128];
29+
};
30+
Pair _pairs[8];
31+
const Pair* _end;
32+
33+
public:
34+
DispIDToStringMap()
35+
: _pairs{}
36+
, _end{ _pairs + ARRAYSIZE(_pairs) }
37+
{
38+
for (auto curr = _pairs; curr != _end; ++curr)
39+
curr->id = DISPID_UNKNOWN;
40+
}
41+
42+
const WCHAR* Find(_In_ DISPID id)
43+
{
44+
for (auto curr = _pairs; curr != _end; ++curr)
45+
{
46+
if (curr->id == id)
47+
return curr->value;
48+
}
49+
50+
return nullptr;
51+
}
52+
53+
void Insert(_In_ DISPID id, _In_z_ const WCHAR* value)
54+
{
55+
if (id == DISPID_UNKNOWN)
56+
throw E_UNEXPECTED;
57+
58+
for (auto curr = _pairs; curr != _end; ++curr)
59+
{
60+
if (curr->id == DISPID_UNKNOWN)
61+
{
62+
curr->id = id;
63+
size_t len = ::wcslen(value) + 1; // Include null
64+
::memcpy(curr->value, value, len * sizeof(value[0]));
65+
return;
66+
}
67+
}
68+
69+
throw E_UNEXPECTED;
70+
}
71+
72+
void Erase(_In_ DISPID id)
73+
{
74+
for (auto curr = _pairs; curr != _end; ++curr)
75+
{
76+
if (curr->id == id)
77+
{
78+
curr->id = DISPID_UNKNOWN;
79+
break;
80+
}
81+
}
82+
}
83+
};
84+
2485
class EventSink : public UnknownImpl, public TestingEvents
2586
{
26-
std::map<DISPID, std::wstring> _firedEvents;
87+
DispIDToStringMap _firedEvents;
2788

2889
public:
2990
void ResetFiredState(_In_ DISPID id)
3091
{
31-
_firedEvents.erase(id);
92+
_firedEvents.Erase(id);
3293
}
3394

3495
bool DidFire(_In_ DISPID id, _Out_ std::wstring& message)
3596
{
36-
auto iter = _firedEvents.find(id);
37-
if (iter == std::end(_firedEvents))
97+
auto value = _firedEvents.Find(id);
98+
if (value == nullptr)
3899
return false;
39100

40-
message = iter->second;
101+
message = value;
41102
return true;
42103
}
43104

@@ -112,7 +173,7 @@ namespace
112173
if (msgMaybe->vt != VT_BSTR)
113174
return E_INVALIDARG;
114175

115-
_firedEvents.insert({ dispId, msgMaybe->bstrVal });
176+
_firedEvents.Insert(dispId, msgMaybe->bstrVal);
116177
return S_OK;
117178
}
118179

0 commit comments

Comments
 (0)