[PUSB] Fix static initialization order fiasco

For details see:
https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
This commit is contained in:
Martino Facchin 2015-10-01 17:35:26 +02:00 committed by Cristian Maglie
parent 66d3eabe42
commit 8cab209ef9
5 changed files with 24 additions and 8 deletions

View File

@ -25,8 +25,6 @@
extern uint8_t _initEndpoints[]; extern uint8_t _initEndpoints[];
PluggableUSB_ PluggableUSB;
int PluggableUSB_::getInterface(uint8_t* interfaceNum) int PluggableUSB_::getInterface(uint8_t* interfaceNum)
{ {
int sent = 0; int sent = 0;
@ -90,6 +88,12 @@ bool PluggableUSB_::plug(PUSBListNode *node)
// restart USB layer??? // restart USB layer???
} }
PluggableUSB_& PluggableUSB()
{
static PluggableUSB_ obj;
return obj;
}
PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT), PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT),
lastEp(CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT), lastEp(CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT),
rootNode(NULL) rootNode(NULL)

View File

@ -66,7 +66,10 @@ private:
PUSBListNode* rootNode; 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 #endif

View File

@ -362,7 +362,7 @@ bool ClassInterfaceRequest(USBSetup& setup)
return CDC_Setup(setup); return CDC_Setup(setup);
#ifdef PLUGGABLE_USB_ENABLED #ifdef PLUGGABLE_USB_ENABLED
return PluggableUSB.setup(setup, i); return PluggableUSB().setup(setup, i);
#endif #endif
return false; return false;
} }
@ -440,7 +440,7 @@ static u8 SendInterfaces()
CDC_GetInterface(&interfaces); CDC_GetInterface(&interfaces);
#ifdef PLUGGABLE_USB_ENABLED #ifdef PLUGGABLE_USB_ENABLED
PluggableUSB.getInterface(&interfaces); PluggableUSB().getInterface(&interfaces);
#endif #endif
return interfaces; return interfaces;
@ -476,7 +476,7 @@ bool SendDescriptor(USBSetup& setup)
InitControl(setup.wLength); InitControl(setup.wLength);
#ifdef PLUGGABLE_USB_ENABLED #ifdef PLUGGABLE_USB_ENABLED
ret = PluggableUSB.getDescriptor(t); ret = PluggableUSB().getDescriptor(t);
if (ret != 0) { if (ret != 0) {
return (ret > 0 ? true : false); return (ret > 0 ? true : false);
} }

View File

@ -21,7 +21,11 @@
#if defined(USBCON) #if defined(USBCON)
HID_ HID; HID_& HID()
{
static HID_ obj;
return obj;
}
int HID_::getInterface(uint8_t* interfaceNum) int HID_::getInterface(uint8_t* interfaceNum)
{ {
@ -113,7 +117,7 @@ HID_::HID_(void) : PUSBListNode(1, 1, epType),
protocol(1), idle(1) protocol(1), idle(1)
{ {
epType[0] = EP_TYPE_INTERRUPT_IN; epType[0] = EP_TYPE_INTERRUPT_IN;
PluggableUSB.plug(this); PluggableUSB().plug(this);
} }
int HID_::begin(void) int HID_::begin(void)

View File

@ -93,6 +93,11 @@ private:
uint8_t idle; 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) } #define D_HIDREPORT(length) { 9, 0x21, 0x01, 0x01, 0, 1, 0x22, lowByte(length), highByte(length) }
#endif // USBCON #endif // USBCON