libdlog: handle thread cancellation 47/213047/1 accepted/tizen/unified/20190830.110653 submit/tizen/20190830.025800
authorMichal Bloch <m.bloch@samsung.com>
Thu, 29 Aug 2019 11:36:54 +0000 (13:36 +0200)
committerMichal Bloch <m.bloch@samsung.com>
Thu, 29 Aug 2019 11:38:01 +0000 (13:38 +0200)
Change-Id: If52fa194ce10aab5e1766ed204c438fa62c03ba3
Signed-off-by: Michal Bloch <m.bloch@samsung.com>
src/libdlog/log.c

index 4c4ff1c..7f14b2a 100644 (file)
@@ -311,6 +311,18 @@ static int __write_to_log(log_id_t log_id, int prio, const char *tag, const char
        if (ret < 0)
                return ret;
 
+       /* Threads can be cancelled before they give up a lock.
+        * Therefore cancellation is temporarily disabled.
+        * This solution is comparatively simple and cheap.
+        * The other solutions (cleanup handlers, robust mutexes)
+        * would be much more complicated and also inflict larger
+        * runtime costs. The downside of disabling cancellation
+        * is not a problem in our case because it is temporary
+        * and very brief so we don't keep an obsolete thread
+        * for much longer than we otherwise would. */
+       int old_cancel_state;
+       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancel_state);
+
        /* The only thing that needs to be protected here is `write_to_log` since
         * all other resources already have their own specific locks (and even the
         * pointer could be made to point at a null handler instead of a true NULL)
@@ -323,7 +335,9 @@ static int __write_to_log(log_id_t log_id, int prio, const char *tag, const char
                ;
                pthread_rwlock_unlock(&log_destruction_lock);
        } else
-               return DLOG_ERROR_NOT_PERMITTED;
+               ret = DLOG_ERROR_NOT_PERMITTED;
+
+       pthread_setcancelstate(old_cancel_state, NULL);
 
        return ret;
 }