From b660d95f889ec4eb9966f36e63b5912590855c96 Mon Sep 17 00:00:00 2001 From: Dario Casalinuovo Date: Tue, 31 May 2016 00:50:06 +0200 Subject: [PATCH] Introduce BAdapterIO * This class is provided as a safe multithreaded communication channel between a BMediaIO-like interface and a Read/Write backend. * Includes internal buffering and can be used to provide multithreaded edit of the data. * Current limitations include missing BOutputAdapter and correct timeout handling. * Future plans provide a BRemoteAdapterIO that using ports and areas allow to easily send big data between processes. --- headers/private/media/AdapterIO.h | 89 ++++++++++++++++ src/kits/media/AdapterIO.cpp | 168 ++++++++++++++++++++++++++++++ src/kits/media/Jamfile | 3 +- 3 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 headers/private/media/AdapterIO.h create mode 100644 src/kits/media/AdapterIO.cpp diff --git a/headers/private/media/AdapterIO.h b/headers/private/media/AdapterIO.h new file mode 100644 index 0000000000..e582b5db9c --- /dev/null +++ b/headers/private/media/AdapterIO.h @@ -0,0 +1,89 @@ +/* + * Copyright 2016 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _ADAPTER_IO_H +#define _ADAPTER_IO_H + + +#include +#include +#include +#include + + +class BAdapterIO; + + +class BInputAdapter { +public: + virtual ssize_t Write(const void* buffer, size_t size); + +private: + friend class BAdapterIO; + + BInputAdapter(BAdapterIO* io); + virtual ~BInputAdapter(); + + BAdapterIO* fIO; + + virtual void _ReservedInputAdapter1(); + virtual void _ReservedInputAdapter2(); + + uint32 _reserved[2]; +}; + + +class BAdapterIO : public BMediaIO { +public: + BAdapterIO(int32 flags, + bigtime_t timeout = B_INFINITE_TIMEOUT); + virtual ~BAdapterIO(); + + virtual void GetFlags(int32* flags) const; + + virtual ssize_t ReadAt(off_t position, void* buffer, + size_t size); + virtual ssize_t WriteAt(off_t position, + const void* buffer, size_t size); + + virtual off_t Seek(off_t position, uint32 seekMode); + virtual off_t Position() const; + + virtual status_t SetSize(off_t size); + virtual status_t GetSize(off_t* size) const; + + BInputAdapter* BuildInputAdapter(); + +protected: + friend class BInputAdapter; + + void SetBuffer(BPositionIO* io); + + ssize_t BackWrite(const void* buffer, size_t size); + +private: + void _WaitForData(size_t size); + + int32 fFlags; + bigtime_t fTimeout; + + off_t fBackPosition; + mutable RWLocker fLock; + BPositionIO* fBuffer; + + BInputAdapter* fInputAdapter; + + BAdapterIO(const BAdapterIO&); + BAdapterIO& operator=(const BAdapterIO&); + + virtual void _ReservedAdapterIO1(); + virtual void _ReservedAdapterIO2(); + virtual void _ReservedAdapterIO3(); + virtual void _ReservedAdapterIO4(); + virtual void _ReservedAdapterIO5(); + + uint32 _reserved[5]; +}; + +#endif // _ADAPTER_IO_H diff --git a/src/kits/media/AdapterIO.cpp b/src/kits/media/AdapterIO.cpp new file mode 100644 index 0000000000..03a2332813 --- /dev/null +++ b/src/kits/media/AdapterIO.cpp @@ -0,0 +1,168 @@ +/* + * Copyright 2016 Dario Casalinuovo. All rights reserved. + * Distributed under the terms of the MIT License. + * + */ + +#include "AdapterIO.h" + +#include + +#include + + +BAdapterIO::BAdapterIO(int32 flags, bigtime_t timeout) + : + fFlags(flags), + fTimeout(timeout), + fBackPosition(0), + fBuffer(NULL), + fInputAdapter(NULL) +{ + fBuffer = new BMallocIO(); +} + + +BAdapterIO::BAdapterIO(const BAdapterIO &) +{ + // copying not allowed... +} + + +BAdapterIO::~BAdapterIO() +{ + delete fInputAdapter; + delete fBuffer; +} + + +void +BAdapterIO::GetFlags(int32* flags) const +{ + *flags = fFlags; +} + + +ssize_t +BAdapterIO::ReadAt(off_t position, void* buffer, size_t size) +{ + printf("read at %d %d \n", (int)position, (int)size); + _WaitForData(position+size); + AutoReadLocker(fLock); + + return fBuffer->ReadAt(position, buffer, size); +} + + +ssize_t +BAdapterIO::WriteAt(off_t position, const void* buffer, size_t size) +{ + _WaitForData(position+size); + AutoWriteLocker(fLock); + + return fBuffer->WriteAt(position, buffer, size); +} + + +off_t +BAdapterIO::Seek(off_t position, uint32 seekMode) +{ + _WaitForData(position); + AutoWriteLocker(fLock); + + return fBuffer->Seek(position, seekMode); +} + + +off_t +BAdapterIO::Position() const +{ + AutoReadLocker(fLock); + + return fBuffer->Position(); +} + + +status_t +BAdapterIO::SetSize(off_t size) +{ + return B_UNSUPPORTED; +} + + +status_t +BAdapterIO::GetSize(off_t* size) const +{ + AutoReadLocker(fLock); + + return fBuffer->GetSize(size); +} + + +BInputAdapter* +BAdapterIO::BuildInputAdapter() +{ + if (fInputAdapter != NULL) + return fInputAdapter; + + fInputAdapter = new BInputAdapter(this); + return fInputAdapter; +} + + +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); +} + + +void +BAdapterIO::_WaitForData(size_t size) +{ + off_t bufferSize = 0; + + status_t ret = GetSize(&bufferSize); + if (ret != B_OK) + return; + + while(bufferSize < size) { + GetSize(&bufferSize); + snooze(100000); + } +} + + +BInputAdapter::BInputAdapter(BAdapterIO* io) + : + fIO(io) +{ +} + + +BInputAdapter::~BInputAdapter() +{ +} + + +ssize_t +BInputAdapter::Write(const void* buffer, size_t size) +{ + return fIO->BackWrite(buffer, size); +} + + +// FBC +void BAdapterIO::_ReservedAdapterIO1() {} +void BAdapterIO::_ReservedAdapterIO2() {} +void BAdapterIO::_ReservedAdapterIO3() {} +void BAdapterIO::_ReservedAdapterIO4() {} +void BAdapterIO::_ReservedAdapterIO5() {} + +void BInputAdapter::_ReservedInputAdapter1() {} +void BInputAdapter::_ReservedInputAdapter2() {} diff --git a/src/kits/media/Jamfile b/src/kits/media/Jamfile index 4ab180eab4..eeefaff467 100644 --- a/src/kits/media/Jamfile +++ b/src/kits/media/Jamfile @@ -25,6 +25,7 @@ for architectureObject in [ MultiArchSubDirSetup ] { Deprecated.cpp MediaRecorder.cpp MediaIO.cpp + AdapterIO.cpp # Public Media Kit Buffer.cpp @@ -92,7 +93,7 @@ for architectureObject in [ MultiArchSubDirSetup ] { StreamerPlugin.cpp WriterPlugin.cpp : - be localestub [ TargetLibsupc++ ] [ TargetLibstdc++ ] + be localestub shared [ TargetLibsupc++ ] [ TargetLibstdc++ ] ; } }