[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xine-cvslog
Subject:    [xine-cvs] HG: xine-ui: Prevent a deadlock in the "tips" main loop.
From:       Lorenzo Desole <lorenzodes () fastwebnet ! it>
Date:       2010-07-17 21:44:03
Message-ID: 139e8d4df48b59e4d4c1.1279365124 () hg ! debian ! org
[Download RAW message or body]

# HG changeset patch
# User Lorenzo Desole <lorenzodes@fastwebnet.it>
# Date 1279365124 0
# Node ID 139e8d4df48b59e4d4c124eb06870d72299a60c9
# Parent  5f6b39fb07467a6b91454358efb54d6178de3530
Prevent a deadlock in the "tips" main loop.

diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 xine-ui (0.99.7) unstable; urgency=low
   (add entries here, newest at the top)
 
+  * Avoid a deadlock in the tooltips code.
   * Set combo box menu windows' override-redirect flags.
   * MRL browser recognises a few more extensions.
   * Fix LIRC library detection (build time).
diff --git a/src/xitk/xine-toolkit/tips.c b/src/xitk/xine-toolkit/tips.c
--- a/src/xitk/xine-toolkit/tips.c
+++ b/src/xitk/xine-toolkit/tips.c
@@ -28,7 +28,7 @@
 #include <inttypes.h>
 #include <unistd.h>
 #include <sys/time.h>
-
+#include <errno.h>
 #include <X11/Xlib.h>
 
 #include "_xitk.h"
@@ -51,28 +51,52 @@
   pthread_cond_t       prewait_cond;
 } tips;
 
+static struct timespec _compute_interval(unsigned int millisecs) {
+  struct timespec ts;
+#if _POSIX_TIMERS > 0
+  clock_gettime(CLOCK_REALTIME, &ts);
+  uint64_t ttimer = (uint64_t)ts.tv_sec*1000 + ts.tv_nsec/1000000 + millisecs;
+  ts.tv_sec = ttimer/1000;
+  ts.tv_nsec = (ttimer%1000)*1000000;
+#else
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  uint64_t ttimer = (uint64_t)tv.tv_sec*1000 + tv.tv_usec/1000 + millisecs;
+  ts.tv_sec = ttimer/1000;
+  ts.tv_nsec = (ttimer%1000)*1000000;
+#endif
+  return ts;
+}
+
+
 static __attribute__((noreturn)) void *_tips_loop_thread(void *data) {
 
   tips.running = 1;
   pthread_mutex_lock(&tips.mutex);
   
   while(tips.running) {
-    struct timeval       tv;
     struct timespec      ts;
 
     /* Wait for a new tip to show */
-    if(!tips.new_widget)
-      pthread_cond_wait(&tips.new_cond, &tips.mutex);
+    if(!tips.new_widget) {
+      while (tips.running) {
+	ts = _compute_interval(1000);
+	if (pthread_cond_timedwait(&tips.new_cond, &tips.mutex, &ts) != ETIMEDOUT)
+	  break;
+      }
+    }
+
+    /* Exit if we're quitting */
+    if (!tips.running)
+      break;
 
     /* Start over if nothing */
     if(!tips.new_widget)
       continue;
     
     tips.prewait = 1;
-    
-    gettimeofday(&tv, NULL);
-    ts.tv_sec  = tv.tv_sec + (tv.tv_usec + 500000) / 1000000;
-    ts.tv_nsec = ((tv.tv_usec + 500000) % 1000000) * 1000;
+
+    ts = _compute_interval(500);
     
     pthread_cond_timedwait(&tips.prewait_cond, &tips.mutex, &ts);
     
@@ -191,11 +215,8 @@
       XMapRaised(tips.display, (xitk_window_get_window(xwin)));
       XUNLOCK(tips.display);
 
-      gettimeofday(&tv, NULL);
-      /* We round to ms instead of us (tips_timeout is ms anyway) to get out most of an int */
-      ts.tv_sec  = tv.tv_sec + ((tv.tv_usec + 500) / 1000 + tips.widget->tips_timeout) / 1000;
-      ts.tv_nsec = (((tv.tv_usec + 500) / 1000 + tips.widget->tips_timeout) % 1000) * 1000000;
-      
+      ts = _compute_interval(tips.widget->tips_timeout);
+
       pthread_cond_timedwait(&tips.timer_cond, &tips.mutex, &ts);
 
       xitk_window_destroy_window(tips.widget->imlibdata, xwin);

------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Xine-cvslog mailing list
Xine-cvslog@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/xine-cvslog
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic