Wake up Cynara async thread from statusCallback 72/109772/2
authorRafal Krypa <r.krypa@samsung.com>
Wed, 11 Jan 2017 08:38:52 +0000 (09:38 +0100)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Thu, 12 Jan 2017 09:14:37 +0000 (01:14 -0800)
Until now the thread handling communication with Cynara was woken up
when new check was prepared for sending because cynara_async_create_request
was expected to trigger statusCallback. When new data is prepared for
sending to Cynara service, statusCallback requests that the cynara descriptor
must be polled for writing and when it's ready, cynara_async_process will
send the data to socket.

But since Cynara release 0.12.0, cynara_async_check_cache may also trigger
a statusCallback. This is because of underlying monotir entries and their
periodic flush to Cynara service. This behavior of Cynara is not documented.

To make sure that security-manager will restart polling of Cynara socket
each time after statusCallback is triggered, the callBack itself will now
take care of waking up the thread responsible for communication with Cynara.

Change-Id: I8f9bf323166fccd97612dd85ec35c9befe5d00f9
Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
src/common/cynara.cpp
src/common/include/cynara.h

index 3be57a71b4ff53ad2426bcbf34ae8c7581afe568..3755002e5fb91fed80dd92d2a872874ffa09e638 100644 (file)
@@ -698,7 +698,7 @@ Cynara::Cynara()
     checkCynaraError(cynara_async_configuration_set_cache_size(p_conf, CACHE_SIZE),
             "Cannot set cynara async configuration cache size");
     checkCynaraError(
-        cynara_async_initialize(&cynara, p_conf, &Cynara::statusCallback, &(pollFds[1])),
+        cynara_async_initialize(&cynara, p_conf, &Cynara::statusCallback, this),
         "Cannot connect to Cynara policy interface.");
 
     thread = std::thread(&Cynara::run, this);
@@ -731,29 +731,34 @@ void Cynara::threadNotifyGet()
         LogError("Unexpected error while reading from eventfd: " << GetErrnoString(errno));
 }
 
-void Cynara::statusCallback(int oldFd, int newFd, cynara_async_status status,
-    void *ptr)
+void Cynara::statusCallback(int oldFd, int newFd, cynara_async_status status)
 {
-    auto cynaraFd = static_cast<struct pollfd *>(ptr);
-
     LogDebug("Cynara status callback. " <<
         "Status = " << status << ", oldFd = " << oldFd << ", newFd = " << newFd);
 
     if (newFd == -1) {
-        cynaraFd->events = 0;
+        pollFds[1].events = 0;
     } else {
-        cynaraFd->fd = newFd;
+        pollFds[1].fd = newFd;
 
         switch (status) {
         case CYNARA_STATUS_FOR_READ:
-            cynaraFd->events = POLLIN;
+            pollFds[1].events = POLLIN;
             break;
 
         case CYNARA_STATUS_FOR_RW:
-            cynaraFd->events = POLLIN | POLLOUT;
+            pollFds[1].events = POLLIN | POLLOUT;
             break;
         }
     }
+
+    threadNotifyPut();
+}
+
+void Cynara::statusCallback(int oldFd, int newFd, cynara_async_status status,
+    void *ptr)
+{
+    static_cast<Cynara *>(ptr)->statusCallback(oldFd, newFd, status);
 }
 
 void Cynara::responseCallback(cynara_check_id checkId,
@@ -855,7 +860,6 @@ bool Cynara::check(const std::string &label, const std::string &privilege,
                 &check_id, &Cynara::responseCallback, &promise),
             "Cannot check permission with Cynara.");
 
-        threadNotifyPut();
         LogDebug("Waiting for response to Cynara query id " << check_id);
     }
 
index 08e8ec6aea418eed413286ede0324ecb4e118c3e..c1da516fe793ea9db464fe8f4447dd1c1c8a5894 100644 (file)
@@ -336,6 +336,9 @@ public:
 
 private:
     static const int CACHE_SIZE = 100;
+
+    void statusCallback(int oldFd, int newFd, cynara_async_status status);
+
     static void statusCallback(int oldFd, int newFd,
         cynara_async_status status, void *ptr);