Timeline: Fix thread synchronization issues during recording.

pull/3/head
Jonathan Moore Liles 2012-06-15 18:53:40 -07:00
parent ab8f23f15d
commit 1f9c2bbb6a
9 changed files with 66 additions and 17 deletions

View File

@ -36,6 +36,8 @@
// #include "const.h"
#include "debug.h"
#include "Mutex.H"
#include <algorithm>
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();

View File

@ -116,3 +116,10 @@ Thread::join ( void )
pthread_join( _thread, NULL );
_thread = 0;
}
void
Thread::exit ( void *retval )
{
pthread_exit( retval );
_thread = 0;
}

View File

@ -52,5 +52,6 @@ public:
bool clone ( void *(*entry_point)(void *), void *arg );
void detach ( void );
void join ( void );
void exit ( void *retval = 0 );
};

View File

@ -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;
}

View File

@ -30,6 +30,7 @@ class Audio_Sequence;
#include "const.h"
#include "debug.h"
#include <unistd.h>
@ -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 *

View File

@ -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;

View File

@ -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" );
}

View File

@ -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();

View File

@ -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;