Bug 1170993: Manage socket buffers in sub-classes of |UnixSocketBuffer|, r=kmachulis

Different users of the socket I/O code have different requirements
for their I/O buffers. This patch moves the buffer management into
sub-classes of |UnixSocketBuffer|. Each of them can maintain memory
according to its needs.
This commit is contained in:
Thomas Zimmermann
2015-06-08 10:20:17 +02:00
parent 419a9b2d66
commit 8b476d2eef
4 changed files with 84 additions and 53 deletions

View File

@@ -42,10 +42,14 @@ static const char sBluetoothdSocketName[] = "bluez_hal_socket";
BluetoothDaemonPDU::BluetoothDaemonPDU(uint8_t aService, uint8_t aOpcode, BluetoothDaemonPDU::BluetoothDaemonPDU(uint8_t aService, uint8_t aOpcode,
uint16_t aPayloadSize) uint16_t aPayloadSize)
: UnixSocketIOBuffer(HEADER_SIZE + aPayloadSize) : mConsumer(nullptr)
, mConsumer(nullptr)
, mUserData(nullptr) , mUserData(nullptr)
{ {
// Allocate memory
size_t availableSpace = HEADER_SIZE + aPayloadSize;
ResetBuffer(new uint8_t[availableSpace], 0, 0, availableSpace);
// Reserve PDU header
uint8_t* data = Append(HEADER_SIZE); uint8_t* data = Append(HEADER_SIZE);
MOZ_ASSERT(data); MOZ_ASSERT(data);
@@ -56,10 +60,18 @@ BluetoothDaemonPDU::BluetoothDaemonPDU(uint8_t aService, uint8_t aOpcode,
} }
BluetoothDaemonPDU::BluetoothDaemonPDU(size_t aPayloadSize) BluetoothDaemonPDU::BluetoothDaemonPDU(size_t aPayloadSize)
: UnixSocketIOBuffer(HEADER_SIZE + aPayloadSize) : mConsumer(nullptr)
, mConsumer(nullptr)
, mUserData(nullptr) , mUserData(nullptr)
{ } {
size_t availableSpace = HEADER_SIZE + aPayloadSize;
ResetBuffer(new uint8_t[availableSpace], 0, 0, availableSpace);
}
BluetoothDaemonPDU::~BluetoothDaemonPDU()
{
nsAutoArrayPtr<uint8_t> data(GetBuffer());
ResetBuffer(nullptr, 0, 0, 0);
}
void void
BluetoothDaemonPDU::GetHeader(uint8_t& aService, uint8_t& aOpcode, BluetoothDaemonPDU::GetHeader(uint8_t& aService, uint8_t& aOpcode,

View File

@@ -56,6 +56,7 @@ public:
BluetoothDaemonPDU(uint8_t aService, uint8_t aOpcode, BluetoothDaemonPDU(uint8_t aService, uint8_t aOpcode,
uint16_t aPayloadSize); uint16_t aPayloadSize);
BluetoothDaemonPDU(size_t aPayloadSize); BluetoothDaemonPDU(size_t aPayloadSize);
~BluetoothDaemonPDU();
void SetConsumer(BluetoothDaemonPDUConsumer* aConsumer) void SetConsumer(BluetoothDaemonPDUConsumer* aConsumer)
{ {

View File

@@ -18,27 +18,18 @@ namespace ipc {
// UnixSocketIOBuffer // UnixSocketIOBuffer
// //
UnixSocketBuffer::UnixSocketBuffer(const void* aData, size_t aSize) UnixSocketBuffer::UnixSocketBuffer()
: mSize(aSize)
, mOffset(0)
, mAvailableSpace(aSize)
{
MOZ_ASSERT(aData || !mSize);
mData = new uint8_t[mAvailableSpace];
memcpy(mData, aData, mSize);
}
UnixSocketBuffer::UnixSocketBuffer(size_t aAvailableSpace)
: mSize(0) : mSize(0)
, mOffset(0) , mOffset(0)
, mAvailableSpace(aAvailableSpace) , mAvailableSpace(0)
{ , mData(nullptr)
mData = new uint8_t[mAvailableSpace]; { }
}
UnixSocketBuffer::~UnixSocketBuffer() UnixSocketBuffer::~UnixSocketBuffer()
{ } {
// Make sure that the caller released the buffer's memory.
MOZ_ASSERT(!GetBuffer());
}
const uint8_t* const uint8_t*
UnixSocketBuffer::Consume(size_t aLen) UnixSocketBuffer::Consume(size_t aLen)
@@ -105,14 +96,6 @@ UnixSocketBuffer::CleanupLeadingSpace()
// UnixSocketIOBuffer // UnixSocketIOBuffer
// //
UnixSocketIOBuffer::UnixSocketIOBuffer(const void* aData, size_t aSize)
: UnixSocketBuffer(aData, aSize)
{ }
UnixSocketIOBuffer::UnixSocketIOBuffer(size_t aAvailableSpace)
: UnixSocketBuffer(aAvailableSpace)
{ }
UnixSocketIOBuffer::~UnixSocketIOBuffer() UnixSocketIOBuffer::~UnixSocketIOBuffer()
{ } { }
@@ -121,12 +104,23 @@ UnixSocketIOBuffer::~UnixSocketIOBuffer()
// //
UnixSocketRawData::UnixSocketRawData(const void* aData, size_t aSize) UnixSocketRawData::UnixSocketRawData(const void* aData, size_t aSize)
: UnixSocketIOBuffer(aData, aSize) {
{ } MOZ_ASSERT(aData || !aSize);
ResetBuffer(static_cast<uint8_t*>(memcpy(new uint8_t[aSize], aData, aSize)),
0, aSize, aSize);
}
UnixSocketRawData::UnixSocketRawData(size_t aSize) UnixSocketRawData::UnixSocketRawData(size_t aSize)
: UnixSocketIOBuffer(aSize) {
{ } ResetBuffer(new uint8_t[aSize], 0, 0, aSize);
}
UnixSocketRawData::~UnixSocketRawData()
{
nsAutoArrayPtr<uint8_t> data(GetBuffer());
ResetBuffer(nullptr, 0, 0, 0);
}
ssize_t ssize_t
UnixSocketRawData::Receive(int aFd) UnixSocketRawData::Receive(int aFd)

View File

@@ -109,15 +109,38 @@ public:
} }
protected: protected:
UnixSocketBuffer();
/* This constructor copies aData of aSize bytes length into the /**
* new instance of |UnixSocketBuffer|. * Sets the raw memory. The caller is responsible for freeing
* this memory.
*
* @param aData A pointer to the buffer's raw memory.
* @param aOffset The start of valid bytes in |aData|.
* @param aSize The number of valid bytes in |aData|.
* @param aAvailableSpace The number of bytes in |aData|.
*/ */
UnixSocketBuffer(const void* aData, size_t aSize); void ResetBuffer(uint8_t* aData,
size_t aOffset, size_t aSize, size_t aAvailableSpace)
{
MOZ_ASSERT(aData || !aAvailableSpace);
MOZ_ASSERT((aOffset + aSize) <= aAvailableSpace);
/* This constructor reserves aAvailableSpace bytes of space. mOffset = aOffset;
mSize = aSize;
mAvailableSpace = aAvailableSpace;
mData = aData;
}
/**
* Retrieves the memory buffer.
*
* @return A pointer to the buffer's raw memory.
*/ */
UnixSocketBuffer(size_t aAvailableSpace); uint8_t* GetBuffer()
{
return mData;
}
size_t GetLeadingSpace() const size_t GetLeadingSpace() const
{ {
@@ -160,7 +183,7 @@ private:
size_t mSize; size_t mSize;
size_t mOffset; size_t mOffset;
size_t mAvailableSpace; size_t mAvailableSpace;
nsAutoArrayPtr<uint8_t> mData; uint8_t* mData;
}; };
// //
@@ -190,17 +213,6 @@ public:
* is the number of bytes written, or a negative value on error. * is the number of bytes written, or a negative value on error.
*/ */
virtual ssize_t Send(int aFd) = 0; virtual ssize_t Send(int aFd) = 0;
protected:
/* This constructor copies aData of aSize bytes length into the
* new instance of |UnixSocketIOBuffer|.
*/
UnixSocketIOBuffer(const void* aData, size_t aSize);
/* This constructor reserves aAvailableSpace bytes of space.
*/
UnixSocketIOBuffer(size_t aAvailableSpace);
}; };
// //
@@ -210,16 +222,28 @@ protected:
class UnixSocketRawData final : public UnixSocketIOBuffer class UnixSocketRawData final : public UnixSocketIOBuffer
{ {
public: public:
/* This constructor copies aData of aSize bytes length into the /**
* This constructor copies aData of aSize bytes length into the
* new instance of |UnixSocketRawData|. * new instance of |UnixSocketRawData|.
*
* @param aData The buffer to copy.
* @param aSize The number of bytes in |aData|.
*/ */
UnixSocketRawData(const void* aData, size_t aSize); UnixSocketRawData(const void* aData, size_t aSize);
/* This constructor reserves aSize bytes of space. Currently /**
* This constructor reserves aSize bytes of space. Currently
* it's only possible to fill this buffer by calling |Receive|. * it's only possible to fill this buffer by calling |Receive|.
*
* @param aSize The number of bytes to allocate.
*/ */
UnixSocketRawData(size_t aSize); UnixSocketRawData(size_t aSize);
/**
* The destructor releases the buffer's raw memory.
*/
~UnixSocketRawData();
/** /**
* Receives data from aFd at the end of the buffer. The returned value * Receives data from aFd at the end of the buffer. The returned value
* is the number of newly received bytes, or 0 if the peer shut down * is the number of newly received bytes, or 0 if the peer shut down