Skip to content

Commit

Permalink
AdapterIO: Increase consistency
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
Numerio committed Jun 22, 2016
1 parent ad89985 commit 6903cf9
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 66 deletions.
4 changes: 1 addition & 3 deletions headers/private/media/AdapterIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,8 @@ class BAdapterIO : public BMediaIO {
int32 fFlags;
bigtime_t fTimeout;

off_t fBackPosition;
mutable RWLocker fLock;

RelativePositionIO* fBuffer;
off_t fTotalSize;

BInputAdapter* fInputAdapter;

Expand Down
157 changes: 94 additions & 63 deletions src/kits/media/AdapterIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{}

virtual ~RelativePositionIO()
{
delete fBuffer;
}

void SetTotalSize(size_t size)
{
fTotalSize = size;
fOwner->GetFlags(&fFlags);
}

size_t TotalSize() const
virtual ~RelativePositionIO()
{
return fTotalSize;
delete fBuffer;
}

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)
Expand All @@ -54,18 +49,25 @@ class RelativePositionIO : public BPositionIO
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;
off_t size = 0;
if (fOwner->GetSize(&size) != B_OK)
return B_ERROR;

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

if (position >= fTotalSize)
off_t bufSize = 0;
if (GetSize(&bufSize) != B_OK)
return B_ERROR;

off_t size = 0;
fBuffer->GetSize(&size);
if (position >= size)
if (position > bufSize)
return B_RESOURCE_UNAVAILABLE;

return B_OK;
Expand All @@ -74,22 +76,22 @@ class RelativePositionIO : public BPositionIO
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;
}

virtual ssize_t ReadAt(off_t position, void* buffer,
size_t size)
{
AutoReadLocker _(fLock);

return fBuffer->ReadAt(
_PositionToRelative(position), buffer, size);

Expand All @@ -98,31 +100,36 @@ class RelativePositionIO : public BPositionIO
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);
Expand All @@ -132,6 +139,31 @@ class RelativePositionIO : public BPositionIO
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
Expand All @@ -144,22 +176,25 @@ class RelativePositionIO : public BPositionIO
return position + fStartOffset;
}

off_t fStartOffset;
off_t fTotalSize;
BAdapterIO* fOwner;
off_t fBackPosition;
off_t fStartOffset;

BPositionIO* fBuffer;
int32 fFlags;

BPositionIO* fBuffer;
mutable RWLocker fLock;
};


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


Expand Down Expand Up @@ -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);
}

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

Expand All @@ -217,25 +248,24 @@ BAdapterIO::Seek(off_t position, uint32 seekMode)
if (ret != B_OK)
return ret;

AutoWriteLocker _(fLock);

return fBuffer->Seek(position, seekMode);
}


off_t
BAdapterIO::Position() const
{
AutoReadLocker _(fLock);

return fBuffer->Position();
}


status_t
BAdapterIO::SetSize(off_t size)
{
AutoWriteLocker _(fLock);
if (!fBuffer->IsMutable()) {
fTotalSize = size;
return B_OK;
}

return fBuffer->SetSize(size);
}
Expand All @@ -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;
}
Expand All @@ -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)
{
Expand Down

0 comments on commit 6903cf9

Please sign in to comment.