]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: fix "static initialization order fiasco" 6978/head
authorMykola Golub <mgolub@mirantis.com>
Fri, 18 Dec 2015 15:10:33 +0000 (17:10 +0200)
committerMykola Golub <mgolub@mirantis.com>
Fri, 18 Dec 2015 19:40:49 +0000 (21:40 +0200)
The order in which static objects in different compilation units are
initialized is undefined. Use static functions as a workaround.

Signed-off-by: Mykola Golub <mgolub@mirantis.com>
src/tools/rbd/Shell.cc
src/tools/rbd/Shell.h

index 57af89a567a647c16fe6b6d0c2f73e8102b488ca..76aa8ed52a14ab79a9e23a9c41ba4ba4f46c8e34 100644 (file)
@@ -66,8 +66,17 @@ std::string format_option_suffix(
 
 } // anonymous namespace
 
-std::vector<Shell::Action *> Shell::s_actions;
-std::set<std::string> Shell::s_switch_arguments;
+std::vector<Shell::Action *>& Shell::get_actions() {
+  static std::vector<Action *> actions;
+
+  return actions;
+}
+
+std::set<std::string>& Shell::get_switch_arguments() {
+  static std::set<std::string> switch_arguments;
+
+  return switch_arguments;
+}
 
 int Shell::execute(int arg_count, const char **arg_values) {
 
@@ -187,9 +196,10 @@ void Shell::get_command_spec(const std::vector<std::string> &arguments,
     } else if (arg[0] == '-') {
       // if the option is not a switch, skip its value
       if (arg.size() >= 2 &&
-          (arg[1] == '-' || s_switch_arguments.count(arg.substr(1, 1)) == 0) &&
+          (arg[1] == '-' ||
+          get_switch_arguments().count(arg.substr(1, 1)) == 0) &&
           (arg[1] != '-' ||
-             s_switch_arguments.count(arg.substr(2, std::string::npos)) == 0) &&
+          get_switch_arguments().count(arg.substr(2, std::string::npos)) == 0) &&
           at::SWITCH_ARGUMENTS.count(arg.substr(2, std::string::npos)) == 0 &&
           arg.find('=') == std::string::npos) {
         ++i;
@@ -202,8 +212,8 @@ void Shell::get_command_spec(const std::vector<std::string> &arguments,
 
 Shell::Action *Shell::find_action(const CommandSpec &command_spec,
                                   CommandSpec **matching_spec) {
-  for (size_t i = 0; i < s_actions.size(); ++i) {
-    Action *action = s_actions[i];
+  for (size_t i = 0; i < get_actions().size(); ++i) {
+    Action *action = get_actions()[i];
     if (action->command_spec.size() <= command_spec.size()) {
       if (std::includes(action->command_spec.begin(),
                         action->command_spec.end(),
@@ -277,7 +287,7 @@ void Shell::print_help() {
             << "Command-line interface for managing Ceph RBD images."
             << std::endl << std::endl;
 
-  std::vector<Action *> actions(s_actions);
+  std::vector<Action *> actions(get_actions());
   std::sort(actions.begin(), actions.end(),
             [](Action *lhs, Action *rhs) { return lhs->command_spec <
                                                     rhs->command_spec; });
@@ -368,8 +378,8 @@ void Shell::print_bash_completion(const CommandSpec &command_spec) {
     print_bash_completion_options(command_opts);
   } else {
     std::cout << "|help";
-    for (size_t i = 0; i < s_actions.size(); ++i) {
-      Action *action = s_actions[i];
+    for (size_t i = 0; i < get_actions().size(); ++i) {
+      Action *action = get_actions()[i];
       std::cout << "|"
                 << joinify<std::string>(action->command_spec.begin(),
                                         action->command_spec.end(), " ");
index 4a21325b3d5f62fb04f43939c14113588d7d8be5..b65483eee48397d2860d854bb8917066df1e932f 100644 (file)
@@ -36,22 +36,22 @@ public:
         : command_spec(command_spec), alias_command_spec(alias_command_spec),
           description(description), help(help), get_arguments(args),
           execute(execute) {
-      Shell::s_actions.push_back(this);
+      Shell::get_actions().push_back(this);
     }
 
   };
 
   struct SwitchArguments {
     SwitchArguments(const std::initializer_list<std::string> &arguments) {
-      Shell::s_switch_arguments.insert(arguments.begin(), arguments.end());
+      Shell::get_switch_arguments().insert(arguments.begin(), arguments.end());
     }
   };
 
   int execute(int arg_count, const char **arg_values);
 
 private:
-  static std::vector<Action *> s_actions;
-  static std::set<std::string> s_switch_arguments;
+  static std::vector<Action *>& get_actions();
+  static std::set<std::string>& get_switch_arguments();
 
   void get_command_spec(const std::vector<std::string> &arguments,
                         std::vector<std::string> *command_spec);