From 65b8430fece7a708be740089864835a862678cff Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 1 Oct 2015 17:35:26 +0200 Subject: [PATCH] [PUSB] Fix static initialization order fiasco For details see: https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use --- hardware/arduino/avr/cores/arduino/PluggableUSB.cpp | 8 ++++++-- hardware/arduino/avr/cores/arduino/PluggableUSB.h | 5 ++++- hardware/arduino/avr/cores/arduino/USBCore.cpp | 6 +++--- hardware/arduino/avr/libraries/HID/HID.cpp | 8 ++++++-- hardware/arduino/avr/libraries/HID/HID.h | 5 +++++ libraries/Keyboard/src/Keyboard.cpp | 4 ++-- libraries/Keyboard/src/Keyboard.h | 1 - libraries/Mouse/src/Mouse.cpp | 4 ++-- libraries/Mouse/src/Mouse.h | 1 - 9 files changed, 28 insertions(+), 14 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp index acc627652..582379a84 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -25,8 +25,6 @@ extern uint8_t _initEndpoints[]; -PluggableUSB_ PluggableUSB; - int PluggableUSB_::getInterface(uint8_t* interfaceNum) { int sent = 0; @@ -90,6 +88,12 @@ bool PluggableUSB_::plug(PUSBListNode *node) // restart USB layer??? } +PluggableUSB_& PluggableUSB() +{ + static PluggableUSB_ obj; + return obj; +} + PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT), lastEp(CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT), rootNode(NULL) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h index 824440a9c..b0668f40e 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.h +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -66,7 +66,10 @@ private: PUSBListNode* rootNode; }; -extern PluggableUSB_ PluggableUSB; +// Replacement for global singleton. +// This function prevents static-initialization-order-fiasco +// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use +PluggableUSB_& PluggableUSB(); #endif diff --git a/hardware/arduino/avr/cores/arduino/USBCore.cpp b/hardware/arduino/avr/cores/arduino/USBCore.cpp index ebdce361f..5db9f521a 100644 --- a/hardware/arduino/avr/cores/arduino/USBCore.cpp +++ b/hardware/arduino/avr/cores/arduino/USBCore.cpp @@ -362,7 +362,7 @@ bool ClassInterfaceRequest(USBSetup& setup) return CDC_Setup(setup); #ifdef PLUGGABLE_USB_ENABLED - return PluggableUSB.setup(setup, i); + return PluggableUSB().setup(setup, i); #endif return false; } @@ -440,7 +440,7 @@ static u8 SendInterfaces() CDC_GetInterface(&interfaces); #ifdef PLUGGABLE_USB_ENABLED - PluggableUSB.getInterface(&interfaces); + PluggableUSB().getInterface(&interfaces); #endif return interfaces; @@ -476,7 +476,7 @@ bool SendDescriptor(USBSetup& setup) InitControl(setup.wLength); #ifdef PLUGGABLE_USB_ENABLED - ret = PluggableUSB.getDescriptor(t); + ret = PluggableUSB().getDescriptor(t); if (ret != 0) { return (ret > 0 ? true : false); } diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index b7aab6cee..ff8e67b2d 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -21,7 +21,11 @@ #if defined(USBCON) -HID_ HID; +HID_& HID() +{ + static HID_ obj; + return obj; +} int HID_::getInterface(uint8_t* interfaceNum) { @@ -113,7 +117,7 @@ HID_::HID_(void) : PUSBListNode(1, 1, epType), protocol(1), idle(1) { epType[0] = EP_TYPE_INTERRUPT_IN; - PluggableUSB.plug(this); + PluggableUSB().plug(this); } int HID_::begin(void) diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index 2cd0f4a0e..a7f5c682f 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -93,6 +93,11 @@ private: uint8_t idle; }; +// Replacement for global singleton. +// This function prevents static-initialization-order-fiasco +// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use +HID_& HID(); + #define D_HIDREPORT(length) { 9, 0x21, 0x01, 0x01, 0, 1, 0x22, lowByte(length), highByte(length) } #endif // USBCON diff --git a/libraries/Keyboard/src/Keyboard.cpp b/libraries/Keyboard/src/Keyboard.cpp index 2663e6e62..d899e92e4 100644 --- a/libraries/Keyboard/src/Keyboard.cpp +++ b/libraries/Keyboard/src/Keyboard.cpp @@ -63,7 +63,7 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = { Keyboard_::Keyboard_(void) { static HIDDescriptorListNode node(_hidReportDescriptor, sizeof(_hidReportDescriptor)); - HID.AppendDescriptor(&node); + HID().AppendDescriptor(&node); } void Keyboard_::begin(void) @@ -76,7 +76,7 @@ void Keyboard_::end(void) void Keyboard_::sendReport(KeyReport* keys) { - HID.SendReport(2,keys,sizeof(KeyReport)); + HID().SendReport(2,keys,sizeof(KeyReport)); } extern diff --git a/libraries/Keyboard/src/Keyboard.h b/libraries/Keyboard/src/Keyboard.h index 1c728ae9e..8f173f31c 100644 --- a/libraries/Keyboard/src/Keyboard.h +++ b/libraries/Keyboard/src/Keyboard.h @@ -94,7 +94,6 @@ public: void releaseAll(void); }; extern Keyboard_ Keyboard; -extern HID_ HID; #endif #endif diff --git a/libraries/Mouse/src/Mouse.cpp b/libraries/Mouse/src/Mouse.cpp index 0cb5b2908..64d02bc86 100644 --- a/libraries/Mouse/src/Mouse.cpp +++ b/libraries/Mouse/src/Mouse.cpp @@ -63,7 +63,7 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = { Mouse_::Mouse_(void) : _buttons(0) { static HIDDescriptorListNode node(_hidReportDescriptor, sizeof(_hidReportDescriptor)); - HID.AppendDescriptor(&node); + HID().AppendDescriptor(&node); } void Mouse_::begin(void) @@ -89,7 +89,7 @@ void Mouse_::move(signed char x, signed char y, signed char wheel) m[1] = x; m[2] = y; m[3] = wheel; - HID.SendReport(1,m,4); + HID().SendReport(1,m,4); } void Mouse_::buttons(uint8_t b) diff --git a/libraries/Mouse/src/Mouse.h b/libraries/Mouse/src/Mouse.h index 3ab57a5eb..2672b5c93 100644 --- a/libraries/Mouse/src/Mouse.h +++ b/libraries/Mouse/src/Mouse.h @@ -55,7 +55,6 @@ public: bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default }; extern Mouse_ Mouse; -extern HID_ HID; #endif #endif \ No newline at end of file