diff --git a/nonlib/Loggable.C b/nonlib/Loggable.C index 89e8d79..1cb7d4a 100644 --- a/nonlib/Loggable.C +++ b/nonlib/Loggable.C @@ -36,6 +36,8 @@ // #include "const.h" #include "debug.h" +#include "Mutex.H" + #include using std::min; using std::max; @@ -64,8 +66,11 @@ void *Loggable::_dirty_callback_arg = NULL; +static Mutex _lock; + Loggable::~Loggable ( ) { + Locker lock( _lock );; _loggables[ _id ].loggable = NULL; } @@ -74,12 +79,15 @@ Loggable::~Loggable ( ) void Loggable::block_start ( void ) { + Locker lock( _lock );; ++Loggable::_level; } void Loggable::block_end ( void ) { + Locker lock( _lock );; + --Loggable::_level; ASSERT( Loggable::_level >= 0, "Programming error" ); @@ -559,6 +567,8 @@ Loggable::compact ( void ) void Loggable::log ( const char *fmt, ... ) { + Locker lock( _lock ); + static char * buf = NULL; static size_t i = 0; static size_t buf_size = 0; @@ -689,6 +699,8 @@ Loggable::log_print( const Log_Entry *o, const Log_Entry *n ) const void Loggable::log_start ( void ) { + Locker lock( _lock );; + if ( ! _old_state ) { _old_state = new Log_Entry; @@ -702,6 +714,8 @@ Loggable::log_start ( void ) void Loggable::log_end ( void ) { + Locker lock( _lock );; + ASSERT( _old_state, "Programming error: log_end() called before log_start()" ); if ( --_nest > 0 ) @@ -737,6 +751,8 @@ Loggable::log_end ( void ) void Loggable::log_create ( void ) const { + Locker lock( _lock );; + set_dirty(); if ( ! _fp ) @@ -786,6 +802,8 @@ Loggable::record_unjournaled ( void ) const void Loggable::log_destroy ( void ) const { + Locker lock( _lock );; + /* the unjournaled state may have changed: make a note of it. */ record_unjournaled(); diff --git a/nonlib/Thread.C b/nonlib/Thread.C index 1a37a8a..cd64e04 100644 --- a/nonlib/Thread.C +++ b/nonlib/Thread.C @@ -116,3 +116,10 @@ Thread::join ( void ) pthread_join( _thread, NULL ); _thread = 0; } + +void +Thread::exit ( void *retval ) +{ + pthread_exit( retval ); + _thread = 0; +} diff --git a/nonlib/Thread.H b/nonlib/Thread.H index a264d20..4c27840 100644 --- a/nonlib/Thread.H +++ b/nonlib/Thread.H @@ -52,5 +52,6 @@ public: bool clone ( void *(*entry_point)(void *), void *arg ); void detach ( void ); void join ( void ); + void exit ( void *retval = 0 ); }; diff --git a/timeline/src/Engine/Audio_Region.C b/timeline/src/Engine/Audio_Region.C index aebce15..b5af742 100644 --- a/timeline/src/Engine/Audio_Region.C +++ b/timeline/src/Engine/Audio_Region.C @@ -175,11 +175,14 @@ Audio_Region::read ( sample_t *buf, nframes_t pos, nframes_t nframes, int channe return cnt; } - /** prepare for capturing */ void Audio_Region::prepare ( void ) { + THREAD_ASSERT( Capture ); + + DMESSAGE( "Preparing capture region" ); + log_start(); } @@ -218,15 +221,10 @@ Audio_Region::finalize ( nframes_t frame ) _range.length = frame - _range.start; - log_end(); - _clip->close(); _clip->open(); - Fl::lock(); - redraw(); - Fl::awake(); - Fl::unlock(); + log_end(); return true; } diff --git a/timeline/src/Engine/Disk_Stream.C b/timeline/src/Engine/Disk_Stream.C index bb94fdc..74d3a9c 100644 --- a/timeline/src/Engine/Disk_Stream.C +++ b/timeline/src/Engine/Disk_Stream.C @@ -30,6 +30,7 @@ class Audio_Sequence; #include "const.h" #include "debug.h" +#include @@ -140,13 +141,23 @@ Disk_Stream::detach ( void ) void Disk_Stream::shutdown ( void ) { - _terminate = true; - - /* try to wake the thread so it'll see that it's time to die */ - block_processed(); - if ( _thread.running() ) + { + _terminate = true; + + /* try to wake the thread so it'll see that it's time to die */ + while ( _terminate ) + { + usleep( 100 ); + block_processed(); + } + _thread.join(); + + sem_destroy( &_blocks ); + + sem_init( &_blocks, 0, 0 ); + } } Track * diff --git a/timeline/src/Engine/Disk_Stream.H b/timeline/src/Engine/Disk_Stream.H index 37300c4..fe63524 100644 --- a/timeline/src/Engine/Disk_Stream.H +++ b/timeline/src/Engine/Disk_Stream.H @@ -94,11 +94,12 @@ protected: virtual void flush ( void ) = 0; void run ( void ); - void shutdown ( void ); void detach ( void ); public: + void shutdown ( void ); + /* must be set before any Disk_Streams are created */ static float seconds_to_buffer; static size_t disk_io_kbytes; diff --git a/timeline/src/Engine/Record_DS.C b/timeline/src/Engine/Record_DS.C index db012d1..629a49e 100644 --- a/timeline/src/Engine/Record_DS.C +++ b/timeline/src/Engine/Record_DS.C @@ -74,10 +74,10 @@ Record_DS::disk_thread ( void ) { _thread.name( "Capture" ); - track()->record( _capture, _frame ); - DMESSAGE( "capture thread running..." ); + track()->record( _capture, _frame ); + const nframes_t nframes = _nframes * _disk_io_blocks; /* buffer to hold the interleaved data returned by the track reader */ @@ -211,7 +211,10 @@ Record_DS::disk_thread ( void ) delete c; _terminate = false; + DMESSAGE( "capture thread gone" ); + + _thread.exit(); } @@ -258,7 +261,7 @@ Record_DS::stop ( nframes_t frame ) _stop_frame = frame; - detach(); +// detach(); DMESSAGE( "recording finished" ); } diff --git a/timeline/src/Engine/Timeline.C b/timeline/src/Engine/Timeline.C index 4fd37b3..783d062 100644 --- a/timeline/src/Engine/Timeline.C +++ b/timeline/src/Engine/Timeline.C @@ -75,6 +75,17 @@ Timeline::stop ( void ) t->record_ds->stop( frame ); } + /* wait until finalization is complete before continuing */ + + DMESSAGE( "Waiting for record threads to shutdown" ); + for ( int i = tracks->children(); i-- ; ) + { + Track *t = (Track*)tracks->child( i ); + + if ( t->armed() && t->record_ds ) + t->record_ds->shutdown(); + } + Loggable::block_end(); activate(); diff --git a/timeline/src/Engine/Track.C b/timeline/src/Engine/Track.C index 881a636..1c9c288 100644 --- a/timeline/src/Engine/Track.C +++ b/timeline/src/Engine/Track.C @@ -304,7 +304,6 @@ Track::finalize ( Capture *c, nframes_t frame ) * them */ c->audio_file->finalize(); - /* peaks get finalized here */ c->region->finalize( frame ); nframes_t capture_offset = 0;