refactoring: group kconn ops into a class 06/203206/4
authorAdrian Szyndela <adrian.s@samsung.com>
Wed, 10 Apr 2019 14:25:24 +0000 (16:25 +0200)
committerAdrian Szyndela <adrian.s@samsung.com>
Thu, 11 Apr 2019 15:16:45 +0000 (17:16 +0200)
This moves functions dealing with kconn into the kconn class.

Change-Id: I27422ae661071ec33d27bced8b2954ea744d16d0

src/libdbuspolicy1.cpp

index eb8a802..f6cf758 100644 (file)
@@ -150,12 +150,63 @@ private:
        NaivePolicyChecker &_checker;
 };
 
-struct kconn {
+/*
+ * kconn is a class which binds together a kdbus connection and a corresponding policy checker.
+ * It has two flavors:
+ * - global objects for system bus and session bus with private connections (static get() method);
+ * - objects created on demand when a client shares his kdbus connection with the library (static get_shared() method).
+ *
+ * Because  the pointer to such object is passed (through void *) to a client, and then clients
+ * pass the pointer to dbuspolicy1_* functions, we always need to maintain the same type,
+ * regardless of the flavor.
+ *
+ * Thread-safety is ensured by C++ and static initialization in static member functions.
+ */
+class kconn {
+public:
        KdbusConnection conn;
-       ldp_xml_parser::NaivePolicyChecker *checker;
-} g_conn[2];
+       NaivePolicyChecker &checker;
+       bool can_be_freed;
 
-static std::once_flag init_once_conn[2];
+       kconn(NaivePolicyChecker &ch, const char *resolved_path)
+               : checker{ch}, can_be_freed{false}
+       {
+               if (conn.connect(resolved_path, 0, _KDBUS_ATTACH_ALL, 0) < 0) {
+                       assert(false && "failed kdbus_connect");
+               }
+       }
+
+       kconn(NaivePolicyChecker &ch, int fd)
+               : checker{ch}, can_be_freed{true}
+       {
+               conn.shared_init_fd(fd);
+       }
+
+       static inline kconn &get(BusType bus_type, const char *resolved_path) {
+               if (SYSTEM_BUS == bus_type)
+                       return system(resolved_path);
+               return session(resolved_path);
+       }
+
+       static inline kconn *get_shared(BusType bus_type, int fd)
+       {
+               kconn *result = new kconn(Checker::get(bus_type).checker(), fd);
+               if (nullptr == result)
+                       LOGE("Error: failed to allocate memory for policy configuration");
+               return result;
+       }
+
+private:
+       static kconn &system(const char *resolved_path) {
+               static kconn c{Checker::system().checker(), resolved_path};
+               return c;
+       }
+       static kconn &session(const char *resolved_path) {
+               static kconn c{Checker::session().checker(), resolved_path};
+               return c;
+       }
+
+};
 
 static std::shared_ptr<const char> bus_type_from_path(const char *bus_path, BusType &bus_type)
 {
@@ -224,40 +275,8 @@ static std::shared_ptr<const char> bus_path_resolve(const char *bus_path, BusTyp
        return resolved_path;
 }
 
-static void init_global_conn_locked(BusType bus_type, std::shared_ptr<const char> resolved_path)
-{
-       struct kconn *kconn = &g_conn[bus_type];
-       kconn->checker = &Checker::get(bus_type).checker();
-
-       if (kconn->conn.connect(resolved_path.get(), 0, _KDBUS_ATTACH_ALL, 0) < 0) {
-               assert(false && "failed kdbus_connect");
-       }
-}
-
-static struct kconn *get_global_conn(BusType bus_type, std::shared_ptr<const char> resolved_path) noexcept
-{
-       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)
-{
-       kconn *result = new kconn;
-       if (nullptr == result) {
-               LOGE("Error: failed to allocate memory for policy configuration");
-               return nullptr;
-       }
-       result->conn.shared_init_fd(fd);
-       result->checker = &Checker::get(bus_type).checker();
-       return result;
-}
-
 DBUSPOLICY1_EXPORT void* dbuspolicy1_init_shared(const char *bus_path, int fd)
 {
-       static_assert(SYSTEM_BUS == 0, "SYSTEM_BUS not 0");
-       static_assert(SESSION_BUS == 1, "SESSION_BUS not 1");
-
        BusType bus_type = SESSION_BUS;
        uid_t bus_owner = 0;
 
@@ -269,12 +288,12 @@ DBUSPOLICY1_EXPORT void* dbuspolicy1_init_shared(const char *bus_path, int fd)
 
        g_udesc.init();
 
-       struct kconn *result = nullptr;
+       kconn *result = nullptr;
        if (Checker::get(bus_type).can_open_owned_by(bus_owner)) {
                if (-1 == fd) {
-                       result = get_global_conn(bus_type, resolved_path);
+                       result = &kconn::get(bus_type, resolved_path.get());
                } else {
-                       result = init_shared_fd(bus_type, fd);
+                       result = kconn::get_shared(bus_type, fd);
                }
        }
 
@@ -298,11 +317,9 @@ DBUSPOLICY1_EXPORT void dbuspolicy1_init_set_pool(void *configuration, void *poo
 
 DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration)
 {
-       for (size_t i = 0; i < sizeof(g_conn)/sizeof(g_conn[0]); i++)
-               if (configuration == &g_conn[i])
-                       return;
-
-       delete KCONN(configuration);
+       auto kconn = KCONN(configuration);
+       if (kconn->can_be_freed)
+               delete kconn;
 }
 
 /*
@@ -361,7 +378,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration,
        auto m_type = toMessageType(message_type);
 
        MatchItemSend sendItem(interface, member, path, m_type, destinationInfo.names());
-       auto decision = kconn->checker->check(g_udesc.uid, g_udesc.gid, g_udesc.label, sendItem);
+       auto decision = kconn->checker.check(g_udesc.uid, g_udesc.gid, g_udesc.label, sendItem);
 
        if (DecisionResult::ALLOW != decision)
                return decisionToRetCode(decision);
@@ -374,10 +391,10 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration,
                return r;
 
        MatchItemReceive receiveItem(interface, member, path, m_type, senderInfo.names());
-       return decisionToRetCode(kconn->checker->check(destinationInfo.uid(),
-                                                                                                  destinationInfo.gid(),
-                                                                                                  destinationInfo.label(),
-                                                                                                  receiveItem));
+       return decisionToRetCode(kconn->checker.check(destinationInfo.uid(),
+                                                                                                 destinationInfo.gid(),
+                                                                                                 destinationInfo.label(),
+                                                                                                 receiveItem));
 }
 
 DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration,
@@ -405,7 +422,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration,
        auto m_type = toMessageType(message_type);
 
        MatchItemSend sendItem(interface, member, path, m_type, info.names());
-       auto decision = kconn->checker->check(sender_uid, sender_gid, sender_label, sendItem);
+       auto decision = kconn->checker.check(sender_uid, sender_gid, sender_label, sendItem);
 
        if (DecisionResult::ALLOW != decision)
                return decisionToRetCode(decision);
@@ -417,18 +434,18 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration,
        KdbusBusNames names;
        MatchItemReceive receiveItem(interface, member, path, m_type, names.addSpaceSeparatedNames(sender));
 
-       return decisionToRetCode(kconn->checker->check(g_udesc.uid,
-                                                                                                  g_udesc.gid,
-                                                                                                  g_udesc.label,
-                                                                                                  receiveItem));
+       return decisionToRetCode(kconn->checker.check(g_udesc.uid,
+                                                                                                 g_udesc.gid,
+                                                                                                 g_udesc.label,
+                                                                                                 receiveItem));
 }
 
 DBUSPOLICY1_EXPORT int dbuspolicy1_can_own(void* configuration, const char* const service)
 {
        tslog::LogLock log_lock;
        auto kconn = KCONN(configuration);
-       return decisionToRetCode(kconn->checker->check(g_udesc.uid,
-                                                                                                  g_udesc.gid,
-                                                                                                  g_udesc.label,
-                                                                                                  MatchItemOwn(service)));
+       return decisionToRetCode(kconn->checker.check(g_udesc.uid,
+                                                                                                 g_udesc.gid,
+                                                                                                 g_udesc.label,
+                                                                                                 MatchItemOwn(service)));
 }