summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2012-01-04 21:07:04 +0000
committerCarl Hetherington <carl@carlh.net>2012-01-04 21:07:04 +0000
commit4e4306d1251aedc294ae8e041f855d136f1c7e8f (patch)
tree637bf40f37a91525135fcae2ff6a067d8897f267
parentc80649d913606bebc34da29d3efaa6b8bd743a32 (diff)
Use Request::Pause rather than Request::Wait for
Butler::wait_until_finished. Otherwise the following bad thing happens: 1. The export code wants to call some Butler functions, so it calls calls Butler::wait_until_finished. 2. This (used to) write Request::Wake into the butler's request pipe. 3. Imagine that when this happens, the butler is already doing stuff. 4. Meanwhile, Butler::wait_until_finished is waiting on Butler::paused. 5. Some time later, the butler finishes its other stuff. 6. Then it signals "paused". 7. This causes Butler::wait_until_finished to return, so the export code thinks everything's ok and starts calling butler functions. 8. Then the butler sees the Request::Wake, wakes up, and by unhappy coincidence ends up calling read on the same diskstream that the export code has just called. This causes corruption of the Diskstream buffers, resulting in mantis #4283. Using Request::Pause instead means that the butler will still wake in step #8, but should_run will be false, so nothing much will happen and the export code will be unimpeded. For future reference, this bug was easiest to track down after adding a debugging mutex to AudioDiskstream and then try-locking it in AudioDiskstream::_do_refill; as far as I can see, _do_refill should never be called by two threads at the git-svn-id: svn://localhost/ardour2/branches/3.0@11163 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/ardour/ardour/butler.h1
-rw-r--r--libs/ardour/butler.cc5
2 files changed, 1 insertions, 5 deletions
diff --git a/libs/ardour/ardour/butler.h b/libs/ardour/ardour/butler.h
index 120f5871f4..061c94d910 100644
--- a/libs/ardour/ardour/butler.h
+++ b/libs/ardour/ardour/butler.h
@@ -60,7 +60,6 @@ class Butler : public SessionHandleRef
struct Request {
enum Type {
- Wake,
Run,
Pause,
Quit
diff --git a/libs/ardour/butler.cc b/libs/ardour/butler.cc
index 5ff4dfcd4d..72b9e5f586 100644
--- a/libs/ardour/butler.cc
+++ b/libs/ardour/butler.cc
@@ -179,9 +179,6 @@ Butler::thread_work ()
switch ((Request::Type) req) {
- case Request::Wake:
- break;
-
case Request::Run:
should_run = true;
break;
@@ -365,7 +362,7 @@ void
Butler::wait_until_finished ()
{
Glib::Mutex::Lock lm (request_lock);
- char c = Request::Wake;
+ char c = Request::Pause;
(void) ::write (request_pipe[1], &c, 1);
paused.wait(request_lock);
}