13
0

kill glib-induced abort caused by asymmetric lock/unlock of diskstream state lock

git-svn-id: svn://localhost/ardour2/trunk@1627 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2007-03-19 19:48:21 +00:00
parent 36d88c8e49
commit fc26b49ac5
6 changed files with 21 additions and 3 deletions

View File

@ -527,6 +527,7 @@ If you still wish to quit, please use the\n\n\
if (session) { if (session) {
session->set_deletion_in_progress (); session->set_deletion_in_progress ();
} }
cerr << "Stopping engine\n";
engine->stop (true); engine->stop (true);
Config->save_state(); Config->save_state();
quit (); quit ();

View File

@ -282,6 +282,7 @@ class Diskstream : public PBD::StatefulDestructible
nframes_t file_frame; nframes_t file_frame;
nframes_t playback_sample; nframes_t playback_sample;
nframes_t playback_distance; nframes_t playback_distance;
bool commit_should_unlock;
uint32_t _read_data_count; uint32_t _read_data_count;
uint32_t _write_data_count; uint32_t _write_data_count;

View File

@ -524,6 +524,8 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
return 0; return 0;
} }
commit_should_unlock = false;
check_record_status (transport_frame, nframes, can_record); check_record_status (transport_frame, nframes, can_record);
nominally_recording = (can_record && re); nominally_recording = (can_record && re);
@ -542,7 +544,7 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
if (!state_lock.trylock()) { if (!state_lock.trylock()) {
return 1; return 1;
} }
commit_should_unlock = true;
adjust_capture_position = 0; adjust_capture_position = 0;
for (chan = c->begin(); chan != c->end(); ++chan) { for (chan = c->begin(); chan != c->end(); ++chan) {
@ -788,6 +790,7 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
be called. unlock the state lock. be called. unlock the state lock.
*/ */
commit_should_unlock = false;
state_lock.unlock(); state_lock.unlock();
} }
@ -827,7 +830,10 @@ AudioDiskstream::commit (nframes_t nframes)
|| c->front()->capture_buf->read_space() >= disk_io_chunk_frames; || c->front()->capture_buf->read_space() >= disk_io_chunk_frames;
} }
state_lock.unlock(); if (commit_should_unlock) {
state_lock.unlock();
}
_processed = false; _processed = false;
return need_butler; return need_butler;

View File

@ -283,9 +283,11 @@ AudioEngine::process_callback (nframes_t nframes)
} }
if (session_remove_pending) { if (session_remove_pending) {
cerr << "engine notes session remove pending\n";
session = 0; session = 0;
session_remove_pending = false; session_remove_pending = false;
session_removed.signal(); session_removed.signal();
cerr << "done, woken waiter\n";
_processed_frames = next_processed_frames; _processed_frames = next_processed_frames;
return 0; return 0;
} }
@ -451,8 +453,10 @@ AudioEngine::remove_session ()
if (_running) { if (_running) {
if (session) { if (session) {
cerr << "mark session for removal\n";
session_remove_pending = true; session_remove_pending = true;
session_removed.wait(_process_lock); session_removed.wait(_process_lock);
cerr << "done\n";
} }
} else { } else {

View File

@ -114,6 +114,7 @@ Diskstream::init (Flag f)
playback_distance = 0; playback_distance = 0;
_read_data_count = 0; _read_data_count = 0;
_write_data_count = 0; _write_data_count = 0;
commit_should_unlock = false;
pending_overwrite = false; pending_overwrite = false;
overwrite_frame = 0; overwrite_frame = 0;
@ -214,7 +215,9 @@ Diskstream::prepare ()
void void
Diskstream::recover () Diskstream::recover ()
{ {
state_lock.unlock(); if (commit_should_unlock) {
state_lock.unlock();
}
_processed = false; _processed = false;
} }

View File

@ -210,6 +210,9 @@ Session::commit_diskstreams (nframes_t nframes, bool &needs_butler)
} }
/* force all diskstreams not handled by a Route to call do their stuff. /* force all diskstreams not handled by a Route to call do their stuff.
Note: the diskstreams that were handled by a route will just return zero
from this call, because they know they were processed. So in fact, this
also runs commit() for every diskstream.
*/ */
if ((dret = (*i)->process (_transport_frame, nframes, 0, actively_recording(), get_rec_monitors_input())) == 0) { if ((dret = (*i)->process (_transport_frame, nframes, 0, actively_recording(), get_rec_monitors_input())) == 0) {