Repository: apache/arrow
File: python/pyarrow/src/arrow/python/helpers.cc (C++)

Code before:
void GetUuidStaticSymbols() {
  OwnedRef uuid_module;

  // Import uuid module
  Status s = ImportModule("uuid", &uuid_module);
  if (!s.ok()) {
    return;
  }

#ifndef Py_GIL_DISABLED
  // Since ImportModule can release the GIL, another thread could have
  // already initialized the static data.
  if (uuid_static_initialized) {
    return;
  }
#endif

  OwnedRef ref;
  if (ImportFromModule(uuid_module.obj(), "UUID", &ref).ok()) {
    uuid_UUID = ref.obj();
  }
}

#ifdef Py_GIL_DISABLED
void InitUuidStaticData() {
  std::call_once(uuid_static_initialized, GetUuidStaticSymbols);
}
#else
void InitUuidStaticData() {
  // NOTE: This is called with the GIL held.  We needn't (and shouldn't,
  // to avoid deadlocks) use an additional C++ lock (ARROW-10519).
  if (uuid_static_initialized) {
    return;
  }
  GetUuidStaticSymbols();
  uuid_static_initialized = true;
}
#endif

}  // namespace

bool IsPyUuid(PyObject* obj) {
  InitUuidStaticData();
  if (!uuid_UUID) return false;
  int result = PyObject_IsInstance(obj, uuid_UUID);
  if (result < 0) {
    PyErr_Clear();
    return false;
  }
  return result == 1;
}

Review comment (bug):
We're duplicating code here between different module imports. It would be really nice to write something like this:
```c++
struct UuidModuleData {
  PyObject* UUID_class = nullptr;
};

UuidModuleData* InitUuidStaticData() {
  static ModuleOnceRunner runner("uuid");
  return runner.Run([&](OwnedRef module) -> UuidModuleData {
    UuidModuleData data;
    OwnedRef ref;
    if (ImportFromModule(module.obj(), "UUID", &ref).ok()) {
      data.UUID_class = ref.obj();
    }
    return data;
  });
}
```

```c++
struct ModuleOnceRunner {
  std::string module_name;
#ifdef Py_GIL_DISABLED
  std::once_flag initialized;
#else
  bool initialized = false;
#endif

  template <typename Func>
  auto Run(Func&& func) -> decltype(func(OwnedRef()) {
    using RetType = decltype(func(OwnedRef());
    RetType ret{};
    auto wrapper_func = [&]() {
      OwnerRef module;
      if (ImportModule("uuid", &module).ok()) {
        ret = func(std::move(module));
      }
    };
#ifdef Py_GIL_DISABLED
    std::call_once(initialized, wrapper_func);
#else
    if (!initialized) {
      initialized = true;
      wrapper_func();
    }
#endif
    return ret;
  };
};

```

I think @rok can help.

Code after:

  explicit ModuleOnceRunner(const std::string& module_name) : module_name(module_name) {}

  template <typename Func>
  void RunOnce(Func&& func) {
    auto do_init = [&]() {
      OwnedRef module;
      if (ImportModule(module_name, &module).ok()) {
#ifndef Py_GIL_DISABLED
        // Since ImportModule can release the GIL, another thread could have
        // already initialized the static data.
        if (initialized) {
          return;
        }
#endif
        func(module);
      }
    };
#ifdef Py_GIL_DISABLED
    std::call_once(initialized, do_init);
#else
    if (!initialized) {
      do_init();
      initialized = true;
    }
#endif
  }
};

static PyObject* uuid_UUID = nullptr;
static ModuleOnceRunner uuid_runner("uuid");

}  // namespace

bool IsPyUuid(PyObject* obj) {
  uuid_runner.RunOnce([](OwnedRef& module) {
    OwnedRef ref;
    if (ImportFromModule(module.obj(), "UUID", &ref).ok()) {
      uuid_UUID = ref.obj();
    }
  });
  if (!uuid_UUID) return false;
  int result = PyObject_IsInstance(obj, uuid_UUID);
  if (result < 0) {
    PyErr_Clear();
    return false;
  }
  return result != 0;
}

namespace {