[Aptitude-svn-commit] r4114 - in branches/aptitude-0.3/aptitude: . src/vscreen

Daniel Burrows dburrows at costa.debian.org
Mon Sep 19 17:43:52 UTC 2005


Author: dburrows
Date: Mon Sep 19 17:43:48 2005
New Revision: 4114

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/vscreen/vscreen.cc
Log:
Fix timeout handling.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Mon Sep 19 17:43:48 2005
@@ -1,3 +1,9 @@
+2005-09-19  Daniel Burrows  <dburrows at debian.org>
+
+	* src/vscreen/vscreen.cc:
+
+	  Fix the timeout thread; it was utterly broken (whoops).
+
 2005-09-17  Daniel Burrows  <dburrows at debian.org>
 
 	* src/generic/problemresolver/problemresolver.h:

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vscreen.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vscreen.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vscreen.cc	Mon Sep 19 17:43:48 2005
@@ -413,14 +413,18 @@
   // The set of active timeouts.
   map<int, timeout_info> timeouts;
 
-  // A lock for the set of timeouts.
+  /** If \b true, the thread should stop. */
+  bool cancelled;
+
+  // A lock for the set of timeouts and the cancelled flag.
   threads::mutex timeouts_mutex;
 
   // A condition to be broadcast when the set of timeouts is expanded
   // by add_timeout.
   threads::condition timeout_added;
 
-  threads::box<bool> running;
+  /** The thread that is currently executing in this object. */
+  threads::box<threads::thread *> running_thread;
 
 
 
@@ -448,7 +452,8 @@
 
   /** timeouts_mutex should be locked when this is called.
    *
-   *  \return the time at which the first active timeout should trigger.
+   *  \param tv_out the time at which the first active timeout should trigger.
+   *  \return \b true if a timeout was found.
    */
   bool first_timeout(timeval &tv_out)
   {
@@ -468,7 +473,10 @@
 	timeval diff;
 	if(timeval_subtract(&diff, &i->second.activate_time, &curtime) == 1 ||
 	   diff.tv_sec == 0 && diff.tv_usec <= 10)
-	  return 0;
+	  {
+	    tv_out = curtime;
+	    return true;
+	  }
 	else
 	  {
 	    if(diff.tv_sec < mintime.tv_sec ||
@@ -494,7 +502,7 @@
   timeout_thread &operator=(const timeout_thread &other);
 
   timeout_thread()
-    : running(false)
+    : cancelled(false), running_thread(NULL)
   {
   }
 
@@ -506,10 +514,16 @@
   // Hence this proxy:
   class timeout_proxy
   {
+    timeout_thread &real_thread;
   public:
+    timeout_proxy(timeout_thread &_real_thread)
+      : real_thread(_real_thread)
+    {
+    }
+
     void operator()() const
     {
-      get_instance()();
+      real_thread();
     }
   };
 public:
@@ -520,20 +534,40 @@
 
   static void start()
   {
-    threads::thread t(timeout_proxy());
+    timeout_thread &instance = get_instance();
+
+    threads::thread *running = instance.running_thread.take();
+    if(running != NULL)
+      {
+	instance.running_thread.put(running);
+	throw SingletonViolationException();
+      }
+
+    instance.running_thread.put(new threads::thread(timeout_proxy(instance)));
   }
 
-  void operator()()
+  static void stop()
   {
-    bool was_running = running.take();
-    running.put(true);
+    timeout_thread &instance = get_instance();
+
+    threads::thread *running = instance.running_thread.take();
+    threads::mutex::lock l(instance.timeouts_mutex);
+
+    instance.cancelled = true;
+    instance.timeout_added.wake_all();
 
-    if(was_running)
-      throw SingletonViolationException();
+    l.release();
 
+    running->join();
+
+    instance.running_thread.put(NULL);
+  }
+
+  void operator()()
+  {
     threads::mutex::lock l(timeouts_mutex);
 
-    while(1)
+    while(!cancelled)
       {
 	timeval next_timeout;
 
@@ -932,6 +966,7 @@
 {
   input_thread::stop();
   signal_thread::stop();
+  timeout_thread::stop();
 
   if(toplevel.valid())
     toplevel->set_owner_window(NULL, 0, 0, 0, 0);
@@ -995,6 +1030,7 @@
 
   input_thread::start();
   signal_thread::start();
+  timeout_thread::start();
 }
 
 void vscreen_redraw()



More information about the Aptitude-svn-commit mailing list