1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-10-26 15:23:48 +01:00

ODDecode task checks blockfile error, making no progress if so...

... also replace explicit mutex locking with RAII and atomics.

This is a part of the big project that handles failure to write block files, as
from disk exhaustion.  ODDecodeBlockFile::WriteODDecodeBlockFile is the one
place calling WriteSimpleBlockFile but not (as in SimpleBlockFile constructor)
throwing an exception.

It is called only when attempting to recover files at open time, or in worker
threads in an EXPERIMENTAL code branch.
This commit is contained in:
Paul Licameli
2016-12-20 11:03:02 -05:00
parent a399d4e23a
commit 5de19dc952
2 changed files with 30 additions and 40 deletions

View File

@@ -47,7 +47,6 @@ ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&baseFileName, wxFileNam
mAliasChannel(aliasChannel) mAliasChannel(aliasChannel)
{ {
mDecoder = NULL; mDecoder = NULL;
mDataAvailable=false;
mAudioFileName = std::move(audioFileName); mAudioFileName = std::move(audioFileName);
mFormat = int16Sample; mFormat = int16Sample;
} }
@@ -59,11 +58,11 @@ ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&existingFile, wxFileNam
SimpleBlockFile{ std::move(existingFile), aliasLen, min, max, rms }, SimpleBlockFile{ std::move(existingFile), aliasLen, min, max, rms },
mType(decodeType), mType(decodeType),
mDataAvailable( dataAvailable ),
mAliasStart(aliasStart), mAliasStart(aliasStart),
mAliasChannel(aliasChannel) mAliasChannel(aliasChannel)
{ {
mDecoder = NULL; mDecoder = NULL;
mDataAvailable=dataAvailable;
mAudioFileName = std::move(audioFileName); mAudioFileName = std::move(audioFileName);
mFormat = int16Sample; mFormat = int16Sample;
} }
@@ -304,11 +303,7 @@ bool ODDecodeBlockFile::IsSummaryAvailable() const
bool ODDecodeBlockFile::IsDataAvailable() const bool ODDecodeBlockFile::IsDataAvailable() const
{ {
bool retval; return mDataAvailable;
mDataAvailableMutex.Lock();
retval= mDataAvailable;
mDataAvailableMutex.Unlock();
return retval;
} }
/// Write the summary to disk, using the derived ReadData() to get the data /// Write the summary to disk, using the derived ReadData() to get the data
@@ -321,43 +316,38 @@ int ODDecodeBlockFile::WriteODDecodeBlockFile()
// derived classes) to get the sample data // derived classes) to get the sample data
SampleBuffer sampleData;// = NewSamples(mLen, floatSample); SampleBuffer sampleData;// = NewSamples(mLen, floatSample);
int ret; int ret;
//use the decoder here.
mDecoderMutex.Lock();
if(!mDecoder)
{ {
mDecoderMutex.Unlock(); //use the decoder here.
return -1; ODLocker locker{ &mDecoderMutex };
if(!mDecoder)
return -1;
//sampleData and mFormat are set by the decoder.
ret = mDecoder->Decode(sampleData, mFormat, mAliasStart, mLen, mAliasChannel);
if(ret < 0) {
printf("ODDecodeBlockFile Decode failure\n");
return ret; //failure
}
} }
{
//sampleData and mFormat are set by the decoder. //the summary is also calculated here.
ret = mDecoder->Decode(sampleData, mFormat, mAliasStart, mLen, mAliasChannel); ODLocker locker{ &mFileNameMutex };
//TODO: we may need to write a version of WriteSimpleBlockFile that uses threadsafe FILE vs wxFile
mDecoderMutex.Unlock(); bool bSuccess =
if(ret < 0) { WriteSimpleBlockFile(
printf("ODDecodeBlockFile Decode failure\n"); sampleData.ptr(),
return ret; //failure mLen,
mFormat,
NULL);
if ( !bSuccess )
return -1;
} }
//the summary is also calculated here. wxAtomicInc( mDataAvailable );
mFileNameMutex.Lock();
//TODO: we may need to write a version of WriteSimpleBlockFile that uses threadsafe FILE vs wxFile
bool bSuccess =
WriteSimpleBlockFile(
sampleData.ptr(),
mLen,
mFormat,
NULL);
wxASSERT(bSuccess); // TODO: Handle failure here by alert to user and undo partial op.
wxUnusedVar(bSuccess);
mFileNameMutex.Unlock();
mDataAvailableMutex.Lock();
mDataAvailable=true;
mDataAvailableMutex.Unlock();
return ret; return ret;
} }

View File

@@ -32,6 +32,7 @@ Also, see ODPCMAliasBlockFile for a similar file.
#include "../ondemand/ODTaskThread.h" #include "../ondemand/ODTaskThread.h"
#include "../DirManager.h" #include "../DirManager.h"
#include "../ondemand/ODDecodeTask.h" #include "../ondemand/ODDecodeTask.h"
#include <wx/atomic.h>
#include <wx/thread.h> #include <wx/thread.h>
/// An AliasBlockFile that references uncompressed data in an existing file /// An AliasBlockFile that references uncompressed data in an existing file
@@ -166,8 +167,7 @@ class ODDecodeBlockFile final : public SimpleBlockFile
///The original file the audio came from. ///The original file the audio came from.
wxFileNameWrapper mAudioFileName; wxFileNameWrapper mAudioFileName;
mutable ODLock mDataAvailableMutex; wxAtomicInt mDataAvailable{ 0 };
bool mDataAvailable;
bool mDataBeingComputed; bool mDataBeingComputed;
ODFileDecoder* mDecoder; ODFileDecoder* mDecoder;