Bug 912996: Remove memcpy when reading from Unix socket, r=qdot

We used to allocate memory on the stack when reading from a file
descriptor and copied the result into an instance of UnixSocketRawData.

This patch

 - cleans up the interface of UnixSocketRawData,
 - removes the large stack allocation (64KiB), and
 - removes the unnecessary memcpy.

Other memcpys for sending data have been moved into the constructor
of UnixSocketRawData.

--HG--
extra : rebase_source : 46ed1c73481732c3f3350bf0bedb56d376c24e98
This commit is contained in:
Thomas Zimmermann 2013-09-06 10:18:35 +02:00
parent 6ab06611af
commit e641d4540e
3 changed files with 29 additions and 20 deletions

View File

@ -137,8 +137,7 @@ PostToRIL(JSContext *cx, unsigned argc, JS::Value *vp)
return false;
}
UnixSocketRawData* raw = new UnixSocketRawData(size);
memcpy(raw->mData, data, raw->mSize);
UnixSocketRawData* raw = new UnixSocketRawData(data, size);
nsRefPtr<SendRilSocketDataTask> task = new SendRilSocketDataTask(clientId, raw);
NS_DispatchToMainThread(task);

View File

@ -677,8 +677,8 @@ UnixSocketConsumer::SendSocketData(const nsACString& aStr)
}
MOZ_ASSERT(!mImpl->IsShutdownOnMainThread());
UnixSocketRawData* d = new UnixSocketRawData(aStr.Length());
memcpy(d->mData, aStr.BeginReading(), aStr.Length());
UnixSocketRawData* d = new UnixSocketRawData(aStr.BeginReading(),
aStr.Length());
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
new SocketSendTask(this, mImpl, d));
return true;
@ -717,8 +717,9 @@ UnixSocketImpl::OnFileCanReadWithoutBlocking(int aFd)
if (status == SOCKET_CONNECTED) {
// Read all of the incoming data.
while (true) {
uint8_t data[MAX_READ_SIZE];
ssize_t ret = read(aFd, data, MAX_READ_SIZE);
nsAutoPtr<UnixSocketRawData> incoming(new UnixSocketRawData(MAX_READ_SIZE));
ssize_t ret = read(aFd, incoming->mData, incoming->mSize);
if (ret <= 0) {
if (ret == -1) {
if (errno == EINTR) {
@ -743,13 +744,13 @@ UnixSocketImpl::OnFileCanReadWithoutBlocking(int aFd)
return;
}
UnixSocketRawData* incoming = new UnixSocketRawData(ret);
memcpy(incoming->mData, data, ret);
nsRefPtr<SocketReceiveTask> t = new SocketReceiveTask(this, incoming);
incoming->mSize = ret;
nsRefPtr<SocketReceiveTask> t =
new SocketReceiveTask(this, incoming.forget());
NS_DispatchToMainThread(t);
// If ret is less than MAX_READ_SIZE, there's no more data in the socket
// for us to read now.
// If ret is less than MAX_READ_SIZE, there's no
// more data in the socket for us to read now.
if (ret < ssize_t(MAX_READ_SIZE)) {
return;
}

View File

@ -42,25 +42,34 @@ union sockaddr_any {
class UnixSocketRawData
{
public:
nsAutoArrayPtr<uint8_t> mData;
// Number of octets in mData.
size_t mSize;
size_t mCurrentWriteOffset;
nsAutoArrayPtr<uint8_t> mData;
/**
* Constructor for situations where size is known beforehand (for example,
* when being assigned strings)
*
* Constructor for situations where only size is known beforehand
* (for example, when being assigned strings)
*/
UnixSocketRawData(int aSize) :
UnixSocketRawData(size_t aSize) :
mSize(aSize),
mCurrentWriteOffset(0)
{
mData = new uint8_t[aSize];
mData = new uint8_t[mSize];
}
/**
* Constructor for situations where size and data is known
* beforehand (for example, when being assigned strings)
*/
UnixSocketRawData(const void* aData, size_t aSize)
: mSize(aSize),
mCurrentWriteOffset(0)
{
MOZ_ASSERT(aData || !mSize);
mData = new uint8_t[mSize];
memcpy(mData, aData, mSize);
}
private:
UnixSocketRawData() {}
};
class UnixSocketImpl;