Skip to content

Commit 65b8430

Browse files
facchinmcmaglie
authored andcommitted
[PUSB] Fix static initialization order fiasco
For details see: https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
1 parent d13aadc commit 65b8430

File tree

9 files changed

+28
-14
lines changed

9 files changed

+28
-14
lines changed

Diff for: hardware/arduino/avr/cores/arduino/PluggableUSB.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525

2626
extern uint8_t _initEndpoints[];
2727

28-
PluggableUSB_ PluggableUSB;
29-
3028
int PluggableUSB_::getInterface(uint8_t* interfaceNum)
3129
{
3230
int sent = 0;
@@ -90,6 +88,12 @@ bool PluggableUSB_::plug(PUSBListNode *node)
9088
// restart USB layer???
9189
}
9290

91+
PluggableUSB_& PluggableUSB()
92+
{
93+
static PluggableUSB_ obj;
94+
return obj;
95+
}
96+
9397
PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT),
9498
lastEp(CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT),
9599
rootNode(NULL)

Diff for: hardware/arduino/avr/cores/arduino/PluggableUSB.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ class PluggableUSB_ {
6666
PUSBListNode* rootNode;
6767
};
6868

69-
extern PluggableUSB_ PluggableUSB;
69+
// Replacement for global singleton.
70+
// This function prevents static-initialization-order-fiasco
71+
// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
72+
PluggableUSB_& PluggableUSB();
7073

7174
#endif
7275

Diff for: hardware/arduino/avr/cores/arduino/USBCore.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ bool ClassInterfaceRequest(USBSetup& setup)
362362
return CDC_Setup(setup);
363363

364364
#ifdef PLUGGABLE_USB_ENABLED
365-
return PluggableUSB.setup(setup, i);
365+
return PluggableUSB().setup(setup, i);
366366
#endif
367367
return false;
368368
}
@@ -440,7 +440,7 @@ static u8 SendInterfaces()
440440
CDC_GetInterface(&interfaces);
441441

442442
#ifdef PLUGGABLE_USB_ENABLED
443-
PluggableUSB.getInterface(&interfaces);
443+
PluggableUSB().getInterface(&interfaces);
444444
#endif
445445

446446
return interfaces;
@@ -476,7 +476,7 @@ bool SendDescriptor(USBSetup& setup)
476476

477477
InitControl(setup.wLength);
478478
#ifdef PLUGGABLE_USB_ENABLED
479-
ret = PluggableUSB.getDescriptor(t);
479+
ret = PluggableUSB().getDescriptor(t);
480480
if (ret != 0) {
481481
return (ret > 0 ? true : false);
482482
}

Diff for: hardware/arduino/avr/libraries/HID/HID.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@
2121

2222
#if defined(USBCON)
2323

24-
HID_ HID;
24+
HID_& HID()
25+
{
26+
static HID_ obj;
27+
return obj;
28+
}
2529

2630
int HID_::getInterface(uint8_t* interfaceNum)
2731
{
@@ -113,7 +117,7 @@ HID_::HID_(void) : PUSBListNode(1, 1, epType),
113117
protocol(1), idle(1)
114118
{
115119
epType[0] = EP_TYPE_INTERRUPT_IN;
116-
PluggableUSB.plug(this);
120+
PluggableUSB().plug(this);
117121
}
118122

119123
int HID_::begin(void)

Diff for: hardware/arduino/avr/libraries/HID/HID.h

+5
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ class HID_ : public PUSBListNode
9393
uint8_t idle;
9494
};
9595

96+
// Replacement for global singleton.
97+
// This function prevents static-initialization-order-fiasco
98+
// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
99+
HID_& HID();
100+
96101
#define D_HIDREPORT(length) { 9, 0x21, 0x01, 0x01, 0, 1, 0x22, lowByte(length), highByte(length) }
97102

98103
#endif // USBCON

Diff for: libraries/Keyboard/src/Keyboard.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = {
6363
Keyboard_::Keyboard_(void)
6464
{
6565
static HIDDescriptorListNode node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
66-
HID.AppendDescriptor(&node);
66+
HID().AppendDescriptor(&node);
6767
}
6868

6969
void Keyboard_::begin(void)
@@ -76,7 +76,7 @@ void Keyboard_::end(void)
7676

7777
void Keyboard_::sendReport(KeyReport* keys)
7878
{
79-
HID.SendReport(2,keys,sizeof(KeyReport));
79+
HID().SendReport(2,keys,sizeof(KeyReport));
8080
}
8181

8282
extern

Diff for: libraries/Keyboard/src/Keyboard.h

-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ class Keyboard_ : public Print
9494
void releaseAll(void);
9595
};
9696
extern Keyboard_ Keyboard;
97-
extern HID_ HID;
9897

9998
#endif
10099
#endif

Diff for: libraries/Mouse/src/Mouse.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = {
6363
Mouse_::Mouse_(void) : _buttons(0)
6464
{
6565
static HIDDescriptorListNode node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
66-
HID.AppendDescriptor(&node);
66+
HID().AppendDescriptor(&node);
6767
}
6868

6969
void Mouse_::begin(void)
@@ -89,7 +89,7 @@ void Mouse_::move(signed char x, signed char y, signed char wheel)
8989
m[1] = x;
9090
m[2] = y;
9191
m[3] = wheel;
92-
HID.SendReport(1,m,4);
92+
HID().SendReport(1,m,4);
9393
}
9494

9595
void Mouse_::buttons(uint8_t b)

Diff for: libraries/Mouse/src/Mouse.h

-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ class Mouse_
5555
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
5656
};
5757
extern Mouse_ Mouse;
58-
extern HID_ HID;
5958

6059
#endif
6160
#endif

0 commit comments

Comments
 (0)