facine / easyBlack

Beaglebone Black C++ Library for GPIO using high performance of mmap.
MIT License
17 stars 7 forks source link

static initialization problems... and suggested fix... #4

Open supertwang opened 8 years ago

supertwang commented 8 years ago

Hi there,

I am running into static initialization order issues with this library in its current form (aka the "Static initialization order fiasco" see: https://isocpp.org/wiki/faq/ctors#static-init-order ).

I was able to fix it in my case by converting the following variables to the "Construct On First Use Idiom" (described just below the above link, on the same page): PIN_INDEX, BSPM_TEMPLATE and BSPWM_TEMPLATE.

The fix (which worked for me) is below, and won't affect the function of the library, just make it more portable/predictable across different compilers. Essentially it just enforces a functional initialization order.

In the memGPIO.cpp:

add the following instead of the current static initialization of the above variables:

const std::map<std::string, const memGPIO::gpioPin> &memGPIO::PIN_INDEX() {
  static const std::map<std::string, const memGPIO::gpioPin> *index = new std::map<std::string, const memGPIO::gpioPin>(memGPIO::initializePins());
  return *index;
}
const std::string &memGPIO::BSPM_TEMPLATE()
{
  static const std::string *tmpl = new std::string(memGPIO::initializeBSPMTemplate());
  return *tmpl;
}
const std::string &memGPIO::BSPWM_TEMPLATE()
{
  static const std::string *tmpl = new std::string( memGPIO::initializeBSPWMTemplate());
  return *tmpl;
}

In memGPIO.hpp, replace the variable declarations with the following function declarations:

  // Available PINs.
  static const std::map <std::string, const gpioPin> &PIN_INDEX();

  // DTS file templates.
  static const std::string &BSPM_TEMPLATE();
  static const std::string &BSPWM_TEMPLATE();

Finally, in memGPIO.cpp, replace all uses of PIN_INDEX with PIN_INDEX(), BSPM_TEMPLATE with BSPM_TEMPLATE(), and PSPWM_TEMPLATE with PSPWM_TEMPLATE().