From 6903cf9bda90f868a88681c4cb616f0b1adb31bb Mon Sep 17 00:00:00 2001 From: Dario Casalinuovo Date: Wed, 22 Jun 2016 21:33:22 +0200 Subject: [PATCH] AdapterIO: Increase consistency * Moved data locking in the internal buffer class, includes handling of backend writes. * Takes advantage of inheritance for getting the size. The choice is made depending on the flags. This allow the implementer to easily return a custom size by reimplementing GetSize. At the same time a plain BAdapterIO can still have it's total size set, but the behavior will change depending it's mutable or not. * Some decisions are now made by considering everything in absolute values. * Other minor fixes. --- headers/private/media/AdapterIO.h | 4 +- src/kits/media/AdapterIO.cpp | 159 ++++++++++++++++++------------ 2 files changed, 96 insertions(+), 67 deletions(-) diff --git a/headers/private/media/AdapterIO.h b/headers/private/media/AdapterIO.h index fcd70186fb..6d48c27cf6 100644 --- a/headers/private/media/AdapterIO.h +++ b/headers/private/media/AdapterIO.h @@ -72,10 +72,8 @@ private: int32 fFlags; bigtime_t fTimeout; - off_t fBackPosition; - mutable RWLocker fLock; - RelativePositionIO* fBuffer; + off_t fTotalSize; BInputAdapter* fInputAdapter; diff --git a/src/kits/media/AdapterIO.cpp b/src/kits/media/AdapterIO.cpp index d7f6e3f545..048fd591b4 100644 --- a/src/kits/media/AdapterIO.cpp +++ b/src/kits/media/AdapterIO.cpp @@ -14,36 +14,31 @@ class RelativePositionIO : public BPositionIO { public: - RelativePositionIO(BPositionIO* buffer) + RelativePositionIO(BAdapterIO* owner, BPositionIO* buffer) : BPositionIO(), + fOwner(owner), + fBackPosition(0), fStartOffset(0), - fTotalSize(0), fBuffer(buffer) - {} + { + fOwner->GetFlags(&fFlags); + } virtual ~RelativePositionIO() { delete fBuffer; } - void SetTotalSize(size_t size) - { - fTotalSize = size; - } - - size_t TotalSize() const - { - return fTotalSize; - } - status_t ResetStartOffset(off_t offset) { status_t ret = fBuffer->SetSize(0); - if (ret == B_OK) - fStartOffset = offset; + if (ret != B_OK) + return ret; - return ret; + fBackPosition = offset; + fStartOffset = offset; + return B_OK; } status_t EvaluatePosition(off_t position) @@ -54,18 +49,25 @@ public: if (position < fStartOffset) return B_RESOURCE_UNAVAILABLE; - // This is an endless stream, we don't know - // how much data will come and when, we could - // block on that. - if (fTotalSize == 0) - return B_WOULD_BLOCK; - - if (position >= fTotalSize) + off_t size = 0; + if (fOwner->GetSize(&size) != B_OK) return B_ERROR; - off_t size = 0; - fBuffer->GetSize(&size); - if (position >= size) + if (position > size) { + // This is an endless stream, we don't know + // how much data will come and when, we could + // block on that. + if (IsMutable()) + return B_WOULD_BLOCK; + else + return B_ERROR; + } + + off_t bufSize = 0; + if (GetSize(&bufSize) != B_OK) + return B_ERROR; + + if (position > bufSize) return B_RESOURCE_UNAVAILABLE; return B_OK; @@ -74,15 +76,13 @@ public: status_t WaitForData(off_t position) { off_t bufferSize = 0; - position = _PositionToRelative(position); - - status_t ret = fBuffer->GetSize(&bufferSize); + status_t ret = GetSize(&bufferSize); if (ret != B_OK) return B_ERROR; while(bufferSize < position) { snooze(100000); - fBuffer->GetSize(&bufferSize); + GetSize(&bufferSize); } return B_OK; } @@ -90,6 +90,8 @@ public: virtual ssize_t ReadAt(off_t position, void* buffer, size_t size) { + AutoReadLocker _(fLock); + return fBuffer->ReadAt( _PositionToRelative(position), buffer, size); @@ -98,31 +100,36 @@ public: virtual ssize_t WriteAt(off_t position, const void* buffer, size_t size) { + AutoWriteLocker _(fLock); + return fBuffer->WriteAt( _PositionToRelative(position), buffer, size); } virtual off_t Seek(off_t position, uint32 seekMode) { + AutoWriteLocker _(fLock); + return fBuffer->Seek(_PositionToRelative(position), seekMode); } virtual off_t Position() const { + AutoReadLocker _(fLock); + return _RelativeToPosition(fBuffer->Position()); } virtual status_t SetSize(off_t size) { + AutoWriteLocker _(fLock); + return fBuffer->SetSize(_PositionToRelative(size)); } virtual status_t GetSize(off_t* size) const { - if (fTotalSize > 0) { - *size = fTotalSize; - return B_OK; - } + AutoReadLocker _(fLock); off_t bufferSize; status_t ret = fBuffer->GetSize(&bufferSize); @@ -132,6 +139,31 @@ public: return ret; } + ssize_t BackWrite(const void* buffer, size_t size) + { + AutoWriteLocker _(fLock); + + off_t currentPos = Position(); + off_t ret = fBuffer->WriteAt(fBackPosition, buffer, size); + fBackPosition += ret; + return fBuffer->Seek(currentPos, SEEK_SET); + } + + bool IsStreaming() const + { + return (fFlags & B_MEDIA_STREAMING) == true; + } + + bool IsMutable() const + { + return (fFlags & B_MEDIA_MUTABLE_SIZE) == true; + } + + bool IsSeekable() const + { + return (fFlags & B_MEDIA_SEEKABLE) == true; + } + private: off_t _PositionToRelative(off_t position) const @@ -144,10 +176,14 @@ private: return position + fStartOffset; } - off_t fStartOffset; - off_t fTotalSize; + BAdapterIO* fOwner; + off_t fBackPosition; + off_t fStartOffset; - BPositionIO* fBuffer; + BPositionIO* fBuffer; + int32 fFlags; + + mutable RWLocker fLock; }; @@ -155,11 +191,10 @@ BAdapterIO::BAdapterIO(int32 flags, bigtime_t timeout) : fFlags(flags), fTimeout(timeout), - fBackPosition(0), fBuffer(NULL), fInputAdapter(NULL) { - fBuffer = new RelativePositionIO(new BMallocIO()); + fBuffer = new RelativePositionIO(this, new BMallocIO()); } @@ -191,8 +226,6 @@ BAdapterIO::ReadAt(off_t position, void* buffer, size_t size) if (ret != B_OK) return ret; - AutoReadLocker _(fLock); - return fBuffer->ReadAt(position, buffer, size); } @@ -204,8 +237,6 @@ BAdapterIO::WriteAt(off_t position, const void* buffer, size_t size) if (ret != B_OK) return ret; - AutoWriteLocker _(fLock); - return fBuffer->WriteAt(position, buffer, size); } @@ -217,8 +248,6 @@ BAdapterIO::Seek(off_t position, uint32 seekMode) if (ret != B_OK) return ret; - AutoWriteLocker _(fLock); - return fBuffer->Seek(position, seekMode); } @@ -226,8 +255,6 @@ BAdapterIO::Seek(off_t position, uint32 seekMode) off_t BAdapterIO::Position() const { - AutoReadLocker _(fLock); - return fBuffer->Position(); } @@ -235,7 +262,10 @@ BAdapterIO::Position() const status_t BAdapterIO::SetSize(off_t size) { - AutoWriteLocker _(fLock); + if (!fBuffer->IsMutable()) { + fTotalSize = size; + return B_OK; + } return fBuffer->SetSize(size); } @@ -244,19 +274,32 @@ BAdapterIO::SetSize(off_t size) status_t BAdapterIO::GetSize(off_t* size) const { - AutoReadLocker _(fLock); + if (!fBuffer->IsMutable()) { + *size = fTotalSize; + return B_OK; + } return fBuffer->GetSize(size); } +ssize_t +BAdapterIO::BackWrite(const void* buffer, size_t size) +{ + return fBuffer->BackWrite(buffer, size); +} + + status_t BAdapterIO::_EvaluateWait(off_t pos) { status_t err = fBuffer->EvaluatePosition(pos); - if (err == B_ERROR && err != B_WOULD_BLOCK) - return B_ERROR; - else if (err == B_RESOURCE_UNAVAILABLE) { + + if (err != B_RESOURCE_UNAVAILABLE && err != B_OK) + return B_UNSUPPORTED; + + if (err == B_RESOURCE_UNAVAILABLE && fBuffer->IsStreaming() + && fBuffer->IsSeekable()) { if (SeekRequested(pos) != B_OK) return B_UNSUPPORTED; } @@ -276,18 +319,6 @@ BAdapterIO::BuildInputAdapter() } -ssize_t -BAdapterIO::BackWrite(const void* buffer, size_t size) -{ - AutoWriteLocker _(fLock); - - off_t currentPos = Position(); - off_t ret = fBuffer->WriteAt(fBackPosition, buffer, size); - fBackPosition += ret; - return fBuffer->Seek(currentPos, SEEK_SET); -} - - status_t BAdapterIO::SeekRequested(off_t position) {