use call_once for initialization 43/202543/3
authorAdrian Szyndela <adrian.s@samsung.com>
Thu, 21 Mar 2019 09:41:37 +0000 (10:41 +0100)
committerAdrian Szyndela <adrian.s@samsung.com>
Mon, 1 Apr 2019 12:09:37 +0000 (14:09 +0200)
Change-Id: I5dae342a7ba7083903d1fa30a4440700629b6945

src/internal/internal.h
src/libdbuspolicy1.cpp

index c5d9ca5..92a1acc 100644 (file)
@@ -66,8 +66,6 @@ int __internal_init_auto_serialized(BusType bus_type, const char* const config_n
 /** Inits tslog.  */
 void __internal_init_once(void);
 
-extern pthread_mutex_t g_mutex;
-
 /** Dumps memory */
 void memory_dump(BusType bus_type);
 
index 92b2d8c..5446bdc 100644 (file)
@@ -30,8 +30,8 @@
 #include <pwd.h>
 #include <grp.h>
 #include <linux/limits.h>
-#include <pthread.h>
 #include <assert.h>
+#include <mutex>
 
 #define KDBUS_PATH_PREFIX "/sys/fs/kdbus/"
 #define KDBUS_SYSTEM_BUS_PATH "/sys/fs/kdbus/0-system/bus"
@@ -52,9 +52,9 @@ struct udesc {
        char label[256];
 } g_udesc;
 
-static bool init_once_done = false;
-static bool init_once_db[2] = {false, false};
-static bool init_once_conn[2] = {false, false};
+static std::once_flag init_once_done;
+static std::once_flag init_once_db[2];
+static std::once_flag init_once_conn[2];
 
 extern "C" void __dbuspolicy1_change_creds(uid_t uid, gid_t gid, const char* label)
 {
@@ -64,23 +64,20 @@ extern "C" void __dbuspolicy1_change_creds(uid_t uid, gid_t gid, const char* lab
                strncpy(g_udesc.label, label, strlen(label) + 1);
 }
 
-static bool dbuspolicy_init_once_locked(void)
+static void dbuspolicy_init_once_locked(void)
 {
-       if (init_once_done)
-               return false;
-
        char buf[1024];
        int attr_fd;
        int r;
 
        attr_fd = open("/proc/self/attr/current", O_RDONLY);
        if (attr_fd < 0)
-               return true;
+               assert(false && "failed open: /proc/self/attr/current");
        r = read(attr_fd, buf, sizeof(buf));
        close(attr_fd);
 
        if (r < 0 || r >= (long int)sizeof(g_udesc.label)) /* read */
-               return true;
+               assert(false && "failed read: /proc/self/attr/current");
        buf[r] = 0;
 
        g_udesc.uid = getuid();
@@ -88,10 +85,6 @@ static bool dbuspolicy_init_once_locked(void)
        snprintf(g_udesc.label, r + 1 /* additional byte for \0 */, "%s", buf);
 
        __internal_init_once();
-
-       init_once_done = true;
-
-       return false;
 }
 
 static bool bus_type_from_path(const char *bus_path, BusType *bus_type, char **pp)
@@ -160,45 +153,33 @@ err:
        return ret;
 }
 
-static bool init_common_locked(BusType bus_type)
+static void init_common_locked(BusType bus_type)
 {
-       dbuspolicy_init_once_locked();
-
-       if (init_once_db[bus_type])
-               return true;
-
        int ret = __internal_init_auto_serialized(bus_type, (bus_type == SYSTEM_BUS) ? system_bus_conf_file_primary() : session_bus_conf_file_primary());
        if (ret < 0)
                ret = __internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_SECONDARY : SESSION_BUS_CONF_FILE_SECONDARY);
 
-       if (ret >= 0) {
+       if (ret >= 0)
                __internal_init_sup_group(bus_type, g_udesc.uid, g_udesc.gid);
-               init_once_db[bus_type] = true;
-       }
-       return ret >= 0;
+       else
+               assert(false && "failed __internal_init");
 }
 
-static struct kconn *init_global_conn_locked(BusType bus_type, const char *resolved_path)
+static void init_global_conn_locked(BusType bus_type, const char *resolved_path)
 {
-       if (init_once_conn[bus_type])
-               return &g_conn[bus_type];
-
-       struct kconn *result = &g_conn[bus_type];
-       if (kdbus_connect(&result->conn, resolved_path, 0, _KDBUS_ATTACH_ALL, 0) < 0)
-               return NULL;
+       struct kconn *kconn = &g_conn[bus_type];
+       kconn->bus_type = bus_type;
 
-       result->bus_type = bus_type;
-       init_once_conn[bus_type] = true;
-
-       return result;
+       if (kdbus_connect(&kconn->conn, resolved_path, 0, _KDBUS_ATTACH_ALL, 0) < 0) {
+               assert(false && "failed kdbus_connect");
+       }
 }
 
-static struct kconn *get_global_conn(BusType bus_type, const char *resolved_path)
+static struct kconn *get_global_conn(BusType bus_type, const char *resolved_path) noexcept
 {
-       pthread_mutex_lock(&g_mutex);
-       struct kconn *result = init_global_conn_locked(bus_type, resolved_path);
-       pthread_mutex_unlock(&g_mutex);
-       return result;
+       std::call_once(init_once_conn[bus_type], init_global_conn_locked, bus_type, resolved_path);
+
+       return &g_conn[bus_type];
 }
 
 static kconn *init_shared_fd(BusType bus_type, int fd)
@@ -213,16 +194,12 @@ static kconn *init_shared_fd(BusType bus_type, int fd)
        return result;
 }
 
-static bool can_open(BusType bus_type, uid_t bus_owner)
+static bool can_open(BusType bus_type, uid_t bus_owner) noexcept
 {
-       pthread_mutex_lock(&g_mutex);
-       bool ret = init_common_locked(bus_type);
-       pthread_mutex_unlock(&g_mutex);
+       std::call_once(init_once_done, dbuspolicy_init_once_locked);
+       std::call_once(init_once_db[bus_type], init_common_locked, bus_type);
 
-       if (ret)
-               return __internal_can_open(bus_type, bus_owner, g_udesc.uid, g_udesc.gid, g_udesc.label) > 0;
-
-       return false;
+       return __internal_can_open(bus_type, bus_owner, g_udesc.uid, g_udesc.gid, g_udesc.label) > 0;
 }
 
 DBUSPOLICY1_EXPORT void* dbuspolicy1_init_shared(const char *bus_path, int fd)