[glib/icu/ucdn] Make the funcs object allocated on demand
diff --git a/src/hb-ucdn.cc b/src/hb-ucdn.cc
index c237ee8..e51f035 100644
--- a/src/hb-ucdn.cc
+++ b/src/hb-ucdn.cc
@@ -231,22 +231,43 @@
     return ucdn_compat_decompose(u, decomposed);
 }
 
+static hb_unicode_funcs_t *static_ucdn_funcs = nullptr;
+
+#ifdef HB_USE_ATEXIT
+static
+void free_static_ucdn_funcs (void)
+{
+  hb_unicode_funcs_destroy (static_ucdn_funcs);
+}
+#endif
+
 extern "C" HB_INTERNAL
 hb_unicode_funcs_t *
 hb_ucdn_get_unicode_funcs (void)
 {
-  static const hb_unicode_funcs_t _hb_ucdn_unicode_funcs = {
-    HB_OBJECT_HEADER_STATIC,
+retry:
+  hb_unicode_funcs_t *funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_ucdn_funcs);
 
-    nullptr, /* parent */
-    true, /* immutable */
-    {
-#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_ucdn_##name,
+  if (unlikely (!funcs))
+  {
+    funcs = hb_unicode_funcs_create (nullptr);
+
+#define HB_UNICODE_FUNC_IMPLEMENT(name) \
+    hb_unicode_funcs_set_##name##_func (funcs, hb_ucdn_##name, nullptr, nullptr);
       HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_UNICODE_FUNC_IMPLEMENT
+
+    hb_unicode_funcs_make_immutable (funcs);
+
+    if (!hb_atomic_ptr_cmpexch (&static_ucdn_funcs, nullptr, funcs)) {
+      hb_unicode_funcs_destroy (funcs);
+      goto retry;
     }
+
+#ifdef HB_USE_ATEXIT
+    atexit (free_static_ucdn_funcs); /* First person registers atexit() callback. */
+#endif
   };
 
-  return const_cast<hb_unicode_funcs_t *> (&_hb_ucdn_unicode_funcs);
+  return funcs;
 }
-