[PATCH 01/13] Add a simple macro for doing one-time global init using virOnce

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Daniel P. Berrange" <berrange@xxxxxxxxxx>

Using virOnce for global initialization is desirable since it
ensures that initialization will always take place when it is
needed, and guarantees it only occurs once. The problem is that
the code to setup a global initializer with proper error
propagation is tedious. This introduces VIR_ONCE_GLOBAL_INIT
macro to simplify this.

Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx>
---
 src/util/threads.h |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/src/util/threads.h b/src/util/threads.h
index e5000ea..8f192cf 100644
--- a/src/util/threads.h
+++ b/src/util/threads.h
@@ -114,4 +114,53 @@ int virThreadLocalSet(virThreadLocalPtr l, void*) ATTRIBUTE_RETURN_CHECK;
 #  error "Either pthreads or Win32 threads are required"
 # endif
 
+
+/**
+ * VIR_ONCE_GLOBAL_INIT:
+ * classname: base classname
+ *
+ * This macro simplifies the setup of a one-time only
+ * global file initializer.
+ *
+ * Assuming a class called "virMyObject", and a method
+ * implemented like:
+ *
+ *  int virMyObjectOnceInit(void) {
+ *      ...do init tasks...
+ *  }
+ *
+ * Then invoking the macro:
+ *
+ *  VIR_ONCE_GLOBAL_INIT(virMyObject)
+ *
+ * Will create a method
+ *
+ *  int virMyObjectInitialize(void);
+ *
+ * Which will ensure that 'virMyObjectOnceInit' is
+ * guaranteed to be invoked exactly once.
+ */
+# define VIR_ONCE_GLOBAL_INIT(classname)                                \
+    static virOnceControl classname ## OnceControl = VIR_ONCE_CONTROL_INITIALIZER; \
+    static virErrorPtr classname ## OnceError = NULL;                   \
+                                                                        \
+    static void classname ## Once(void)                                 \
+    {                                                                   \
+        if (classname ## OnceInit() < 0)                                \
+            classname ## OnceError = virSaveLastError();                \
+    }                                                                   \
+                                                                        \
+    static int classname ## Initialize(void)                            \
+    {                                                                   \
+        if (virOnce(&classname ## OnceControl, classname ## Once) < 0)  \
+            return -1;                                                  \
+                                                                        \
+        if (classname ## OnceError) {                                   \
+            virSetError(classname ## OnceError);                        \
+            return -1;                                                  \
+        }                                                               \
+                                                                        \
+        return 0;                                                       \
+    }
+
 #endif
-- 
1.7.10.2

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]