Add a _full_condition to so that ::write() sleeps if there is lots of writing to...
authorCarl Hetherington <cth@carlh.net>
Fri, 10 Jan 2014 10:26:02 +0000 (10:26 +0000)
committerCarl Hetherington <cth@carlh.net>
Fri, 10 Jan 2014 10:26:02 +0000 (10:26 +0000)
ChangeLog
src/lib/writer.cc
src/lib/writer.h

index e912c796a2b596027e409e0c0b3e3f6b4155d33e..361eea36a635b6916bc0e92c83b28cb686762238 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2014-01-10  Carl Hetherington  <cth@carlh.net>
 
+       * Try to stop the queue of things to write filling up excessively
+       on fast CPUs.
+
        * Try to fix double "are you sure" prompt on quitting with active jobs.
 
 2014-01-09  Carl Hetherington  <cth@carlh.net>
index 01bb2525e8a7c5f843aeecd6948079f050f6366e..cc3b875964dfac0b4cfb8833fa4a2b1dc5100194 100644 (file)
@@ -129,6 +129,10 @@ Writer::write (shared_ptr<const EncodedData> encoded, int frame, Eyes eyes)
 {
        boost::mutex::scoped_lock lock (_mutex);
 
+       while (_queued_full_in_memory > _maximum_frames_in_memory) {
+               _full_condition.wait (lock);
+       }
+
        QueueItem qi;
        qi.type = QueueItem::FULL;
        qi.encoded = encoded;
@@ -148,7 +152,7 @@ Writer::write (shared_ptr<const EncodedData> encoded, int frame, Eyes eyes)
                ++_queued_full_in_memory;
        }
        
-       _condition.notify_all ();
+       _empty_condition.notify_all ();
 }
 
 void
@@ -156,6 +160,10 @@ Writer::fake_write (int frame, Eyes eyes)
 {
        boost::mutex::scoped_lock lock (_mutex);
 
+       while (_queued_full_in_memory > _maximum_frames_in_memory) {
+               _full_condition.wait (lock);
+       }
+       
        FILE* ifi = fopen_boost (_film->info_path (frame, eyes), "r");
        libdcp::FrameInfo info (ifi);
        fclose (ifi);
@@ -174,7 +182,7 @@ Writer::fake_write (int frame, Eyes eyes)
                _queue.push_back (qi);
        }
 
-       _condition.notify_all ();
+       _empty_condition.notify_all ();
 }
 
 /** This method is not thread safe */
@@ -229,7 +237,7 @@ try
                        }
 
                        TIMING (N_("writer sleeps with a queue of %1"), _queue.size());
-                       _condition.wait (lock);
+                       _empty_condition.wait (lock);
                        TIMING (N_("writer wakes with a queue of %1"), _queue.size());
                }
 
@@ -345,7 +353,8 @@ Writer::finish ()
        
        boost::mutex::scoped_lock lock (_mutex);
        _finish = true;
-       _condition.notify_all ();
+       _empty_condition.notify_all ();
+       _full_condition.notify_all ();
        lock.unlock ();
 
        _thread->join ();
@@ -433,7 +442,9 @@ Writer::finish ()
        meta.set_issue_date_now ();
        dcp.write_xml (_film->interop (), meta, _film->is_signed() ? make_signer () : shared_ptr<const libdcp::Signer> ());
 
-       _film->log()->log (String::compose (N_("Wrote %1 FULL, %2 FAKE, %3 REPEAT; %4 pushed to disk"), _full_written, _fake_written, _repeat_written, _pushed_to_disk));
+       _film->log()->log (
+               String::compose (N_("Wrote %1 FULL, %2 FAKE, %3 REPEAT; %4 pushed to disk"), _full_written, _fake_written, _repeat_written, _pushed_to_disk)
+               );
 }
 
 /** Tell the writer that frame `f' should be a repeat of the frame before it */
@@ -442,6 +453,10 @@ Writer::repeat (int f, Eyes e)
 {
        boost::mutex::scoped_lock lock (_mutex);
 
+       while (_queued_full_in_memory > _maximum_frames_in_memory) {
+               _full_condition.wait (lock);
+       }
+       
        QueueItem qi;
        qi.type = QueueItem::REPEAT;
        qi.frame = f;
@@ -455,7 +470,7 @@ Writer::repeat (int f, Eyes e)
                _queue.push_back (qi);
        }
 
-       _condition.notify_all ();
+       _empty_condition.notify_all ();
 }
 
 bool
index 842d6a55d3079474a03b7feab81757c6b5313711..e2807d71240612090aed3541d641fd9b9619c0ca 100644 (file)
@@ -103,8 +103,10 @@ private:
        int _queued_full_in_memory;
        /** mutex for thread state */
        mutable boost::mutex _mutex;
-       /** condition to manage thread wakeups */
-       boost::condition _condition;
+       /** condition to manage thread wakeups when we have nothing to do  */
+       boost::condition _empty_condition;
+       /** condition to manage thread wakeups when we have too much to do */
+       boost::condition _full_condition;
        /** the data of the last written frame, or 0 if there isn't one */
        boost::shared_ptr<const EncodedData> _last_written[EYES_COUNT];
        /** the index of the last written frame */