Backed out 6 changesets (bug 1059813) by request.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 03 Sep 2014 11:29:16 -0400
changeset 203375 927da4815ef94ee899995fd92387120e197db31e
parent 203374 142047b2389e5f9b6037a9b27e08666840ed7271
child 203376 e934b3bc1feafc77fafcdd08da9c6a163ba20f5b
push id48665
push userryanvm@gmail.com
push dateWed, 03 Sep 2014 20:40:15 +0000
treeherdermozilla-inbound@0da762e6868a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1059813
milestone35.0a1
backs outcffeecd46cade055f3762b4a9ab2fb0bbe34ce70
f991f546dbcdc00086d3cebbbd7a06232204e088
ab4056a1aa06d05695a4ecfff2ee7d0356fa3cff
d08a91fee65a4e4c95fe92e2dbc28b5a13633d78
7bd0ecf96e592fc7050c06236d340decdd65668e
0b7a62175398573e7551cc39a14f91d32278fc29
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 6 changesets (bug 1059813) by request. Backed out changeset cffeecd46cad (bug 1059813) Backed out changeset f991f546dbcd (bug 1059813) Backed out changeset ab4056a1aa06 (bug 1059813) Backed out changeset d08a91fee65a (bug 1059813) Backed out changeset 7bd0ecf96e59 (bug 1059813) Backed out changeset 0b7a62175398 (bug 1059813)
dom/bluetooth/bluedroid/BluetoothOppManager.cpp
dom/bluetooth/bluez/BluetoothHfpManager.cpp
dom/bluetooth/bluez/BluetoothOppManager.cpp
dom/bluetooth2/bluedroid/BluetoothOppManager.cpp
dom/bluetooth2/bluez/BluetoothHfpManager.cpp
dom/bluetooth2/bluez/BluetoothOppManager.cpp
dom/nfc/gonk/NfcService.cpp
ipc/keystore/KeyStore.cpp
ipc/ril/Ril.cpp
ipc/unixsocket/SocketBase.cpp
ipc/unixsocket/SocketBase.h
--- a/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
@@ -746,110 +746,107 @@ BluetoothOppManager::ValidateFileName()
 }
 
 bool
 BluetoothOppManager::ComposePacket(uint8_t aOpCode, UnixSocketRawData* aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aMessage);
 
-  const uint8_t* data = aMessage->GetData();
   int frameHeaderLength = 0;
 
   // See if this is the first part of each Put packet
   if (mPutPacketReceivedLength == 0) {
     // Section 3.3.3 "Put", IrOBEX 1.2
     // [opcode:1][length:2][Headers:var]
     frameHeaderLength = 3;
 
-    mPacketLength = ((static_cast<int>(data[1]) << 8) | data[2]) -
-                    frameHeaderLength;
-
+    mPacketLength = ((((int)aMessage->mData[1]) << 8) | aMessage->mData[2]) -
+                      frameHeaderLength;
     /**
      * A PUT request from remote devices may be divided into multiple parts.
      * In other words, one request may need to be received multiple times,
      * so here we keep a variable mPutPacketReceivedLength to indicate if
      * current PUT request is done.
      */
     mReceivedDataBuffer = new uint8_t[mPacketLength];
     mPutFinalFlag = (aOpCode == ObexRequestCode::PutFinal);
   }
 
-  int dataLength = aMessage->GetSize() - frameHeaderLength;
+  int dataLength = aMessage->mSize - frameHeaderLength;
 
   // Check length before memcpy to prevent from memory pollution
   if (dataLength < 0 ||
       mPutPacketReceivedLength + dataLength > mPacketLength) {
     BT_LOGR("Received packet size is unreasonable");
 
     ReplyToPut(mPutFinalFlag, false);
     DeleteReceivedFile();
     FileTransferComplete();
 
     return false;
   }
 
   memcpy(mReceivedDataBuffer.get() + mPutPacketReceivedLength,
-         &data[frameHeaderLength], dataLength);
+         &aMessage->mData[frameHeaderLength], dataLength);
 
   mPutPacketReceivedLength += dataLength;
 
   return (mPutPacketReceivedLength == mPacketLength);
 }
 
 void
 BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   uint8_t opCode;
-  int receivedLength = aMessage->GetSize();
-  const uint8_t* data = aMessage->GetData();
+  int receivedLength = aMessage->mSize;
 
   if (mPutPacketReceivedLength > 0) {
     opCode = mPutFinalFlag ? ObexRequestCode::PutFinal : ObexRequestCode::Put;
   } else {
-    opCode = data[0];
+    opCode = aMessage->mData[0];
 
     // When there's a Put packet right after a PutFinal packet,
     // which means it's the start point of a new file.
     if (mPutFinalFlag &&
         (opCode == ObexRequestCode::Put ||
          opCode == ObexRequestCode::PutFinal)) {
       mNewFileFlag = true;
       AfterFirstPut();
     }
   }
 
   ObexHeaderSet pktHeaders(opCode);
   if (opCode == ObexRequestCode::Connect) {
     // Section 3.3.1 "Connect", IrOBEX 1.2
     // [opcode:1][length:2][version:1][flags:1][MaxPktSizeWeCanReceive:2]
     // [Headers:var]
-    if (!ParseHeaders(&data[7], receivedLength - 7, &pktHeaders)) {
+    if (!ParseHeaders(&aMessage->mData[7], receivedLength - 7, &pktHeaders)) {
       ReplyError(ObexResponseCode::BadRequest);
       return;
     }
 
     ReplyToConnect();
     AfterOppConnected();
   } else if (opCode == ObexRequestCode::Abort) {
     // Section 3.3.5 "Abort", IrOBEX 1.2
     // [opcode:1][length:2][Headers:var]
-    if (!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
+    if (!ParseHeaders(&aMessage->mData[3], receivedLength - 3, &pktHeaders)) {
       ReplyError(ObexResponseCode::BadRequest);
       return;
     }
 
     ReplyToDisconnectOrAbort();
     DeleteReceivedFile();
   } else if (opCode == ObexRequestCode::Disconnect) {
     // Section 3.3.2 "Disconnect", IrOBEX 1.2
     // [opcode:1][length:2][Headers:var]
-    if (!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
+    if (!ParseHeaders(&aMessage->mData[3], receivedLength - 3, &pktHeaders)) {
       ReplyError(ObexResponseCode::BadRequest);
       return;
     }
 
     ReplyToDisconnectOrAbort();
     AfterOppDisconnected();
     FileTransferComplete();
   } else if (opCode == ObexRequestCode::Put ||
@@ -922,18 +919,17 @@ BluetoothOppManager::ServerDataHandler(U
   }
 }
 
 void
 BluetoothOppManager::ClientDataHandler(UnixSocketRawData* aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  const uint8_t* data = aMessage->GetData();
-  uint8_t opCode = data[0];
+  uint8_t opCode = aMessage->mData[0];
 
   // Check response code and send out system message as finished if the response
   // code is somehow incorrect.
   uint8_t expectedOpCode = ObexResponseCode::Success;
   if (mLastCommand == ObexRequestCode::Put) {
     expectedOpCode = ObexResponseCode::Continue;
   }
 
@@ -980,19 +976,20 @@ BluetoothOppManager::ClientDataHandler(U
     }
   } else if (mLastCommand == ObexRequestCode::Connect) {
     MOZ_ASSERT(!mFileName.IsEmpty());
     MOZ_ASSERT(mBlob);
 
     AfterOppConnected();
 
     // Keep remote information
-    mRemoteObexVersion = data[3];
-    mRemoteConnectionFlags = data[4];
-    mRemoteMaxPacketLength = ((static_cast<int>(data[5]) << 8) | data[6]);
+    mRemoteObexVersion = aMessage->mData[3];
+    mRemoteConnectionFlags = aMessage->mData[4];
+    mRemoteMaxPacketLength =
+      (((int)(aMessage->mData[5]) << 8) | aMessage->mData[6]);
 
     // The length of file name exceeds maximum length.
     int fileNameByteLen = (mFileName.Length() + 1) * 2;
     int headerLen = kPutRequestHeaderSize + kPutRequestAppendHeaderSize;
     if (fileNameByteLen > mRemoteMaxPacketLength - headerLen) {
       BT_WARNING("The length of file name is aberrant.");
       SendDisconnectRequest();
       return;
@@ -1251,17 +1248,18 @@ void
 BluetoothOppManager::SendObexData(uint8_t* aData, uint8_t aOpcode, int aSize)
 {
   SetObexPacketInfo(aData, aOpcode, aSize);
 
   if (!mIsServer) {
     mLastCommand = aOpcode;
   }
 
-  UnixSocketRawData* s = new UnixSocketRawData(aData, aSize);
+  UnixSocketRawData* s = new UnixSocketRawData(aSize);
+  memcpy(s->mData, aData, s->mSize);
   mSocket->SendSocketData(s);
 }
 
 void
 BluetoothOppManager::FileTransferComplete()
 {
   if (mSendTransferCompleteFlag) {
     return;
--- a/dom/bluetooth/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
@@ -702,18 +702,17 @@ BluetoothHfpManager::HandleShutdown()
 // Virtual function of class SocketConsumer
 void
 BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
                                        nsAutoPtr<UnixSocketRawData>& aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aSocket);
 
-  nsAutoCString msg(reinterpret_cast<const char*>(aMessage->GetData()),
-                    aMessage->GetSize());
+  nsAutoCString msg((const char*)aMessage->mData.get(), aMessage->mSize);
   msg.StripWhitespace();
 
   nsTArray<nsCString> atCommandValues;
 
   // For more information, please refer to 4.34.1 "Bluetooth Defined AT
   // Capabilities" in Bluetooth hands-free profile 1.6
   if (msg.Find("AT+BRSF=") != -1) {
 #ifdef MOZ_B2G_RIL
--- a/dom/bluetooth/bluez/BluetoothOppManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothOppManager.cpp
@@ -769,108 +769,106 @@ BluetoothOppManager::ValidateFileName()
 
 bool
 BluetoothOppManager::ComposePacket(uint8_t aOpCode, UnixSocketRawData* aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aMessage);
 
   int frameHeaderLength = 0;
-  const uint8_t* data = aMessage->GetData();
 
   // See if this is the first part of each Put packet
   if (mPutPacketReceivedLength == 0) {
     // Section 3.3.3 "Put", IrOBEX 1.2
     // [opcode:1][length:2][Headers:var]
     frameHeaderLength = 3;
 
-    mPacketLength = ((static_cast<int>(data[1]) << 8) | data[2]) -
-                    frameHeaderLength;
+    mPacketLength = ((((int)aMessage->mData[1]) << 8) | aMessage->mData[2]) -
+                      frameHeaderLength;
     /**
      * A PUT request from remote devices may be divided into multiple parts.
      * In other words, one request may need to be received multiple times,
      * so here we keep a variable mPutPacketReceivedLength to indicate if
      * current PUT request is done.
      */
     mReceivedDataBuffer = new uint8_t[mPacketLength];
     mPutFinalFlag = (aOpCode == ObexRequestCode::PutFinal);
   }
 
-  int dataLength = aMessage->GetSize() - frameHeaderLength;
+  int dataLength = aMessage->mSize - frameHeaderLength;
 
   // Check length before memcpy to prevent from memory pollution
   if (dataLength < 0 ||
       mPutPacketReceivedLength + dataLength > mPacketLength) {
     BT_LOGR("Received packet size is unreasonable");
 
     ReplyToPut(mPutFinalFlag, false);
     DeleteReceivedFile();
     FileTransferComplete();
 
     return false;
   }
 
   memcpy(mReceivedDataBuffer.get() + mPutPacketReceivedLength,
-         &data[frameHeaderLength], dataLength);
+         &aMessage->mData[frameHeaderLength], dataLength);
 
   mPutPacketReceivedLength += dataLength;
 
   return (mPutPacketReceivedLength == mPacketLength);
 }
 
 void
 BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   uint8_t opCode;
-  int receivedLength = aMessage->GetSize();
-  const uint8_t* data = aMessage->GetData();
+  int receivedLength = aMessage->mSize;
 
   if (mPutPacketReceivedLength > 0) {
     opCode = mPutFinalFlag ? ObexRequestCode::PutFinal : ObexRequestCode::Put;
   } else {
-    opCode = data[0];
+    opCode = aMessage->mData[0];
 
     // When there's a Put packet right after a PutFinal packet,
     // which means it's the start point of a new file.
     if (mPutFinalFlag &&
         (opCode == ObexRequestCode::Put ||
          opCode == ObexRequestCode::PutFinal)) {
       mNewFileFlag = true;
       AfterFirstPut();
     }
   }
 
   ObexHeaderSet pktHeaders(opCode);
   if (opCode == ObexRequestCode::Connect) {
     // Section 3.3.1 "Connect", IrOBEX 1.2
     // [opcode:1][length:2][version:1][flags:1][MaxPktSizeWeCanReceive:2]
     // [Headers:var]
-    if (!ParseHeaders(&data[7], receivedLength - 7, &pktHeaders)) {
+    if (!ParseHeaders(&aMessage->mData[7], receivedLength - 7, &pktHeaders)) {
       ReplyError(ObexResponseCode::BadRequest);
       return;
     }
 
     ReplyToConnect();
     AfterOppConnected();
   } else if (opCode == ObexRequestCode::Abort) {
     // Section 3.3.5 "Abort", IrOBEX 1.2
     // [opcode:1][length:2][Headers:var]
-    if (!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
+    if (!ParseHeaders(&aMessage->mData[3], receivedLength - 3, &pktHeaders)) {
       ReplyError(ObexResponseCode::BadRequest);
       return;
     }
 
     ReplyToDisconnectOrAbort();
     DeleteReceivedFile();
   } else if (opCode == ObexRequestCode::Disconnect) {
     // Section 3.3.2 "Disconnect", IrOBEX 1.2
     // [opcode:1][length:2][Headers:var]
-    if (!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
+    if (!ParseHeaders(&aMessage->mData[3], receivedLength - 3, &pktHeaders)) {
       ReplyError(ObexResponseCode::BadRequest);
       return;
     }
 
     ReplyToDisconnectOrAbort();
     AfterOppDisconnected();
     FileTransferComplete();
   } else if (opCode == ObexRequestCode::Put ||
@@ -943,18 +941,17 @@ BluetoothOppManager::ServerDataHandler(U
   }
 }
 
 void
 BluetoothOppManager::ClientDataHandler(UnixSocketRawData* aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  const uint8_t* data = aMessage->GetData();
-  uint8_t opCode = data[0];
+  uint8_t opCode = aMessage->mData[0];
 
   // Check response code and send out system message as finished if the response
   // code is somehow incorrect.
   uint8_t expectedOpCode = ObexResponseCode::Success;
   if (mLastCommand == ObexRequestCode::Put) {
     expectedOpCode = ObexResponseCode::Continue;
   }
 
@@ -1001,19 +998,20 @@ BluetoothOppManager::ClientDataHandler(U
     }
   } else if (mLastCommand == ObexRequestCode::Connect) {
     MOZ_ASSERT(!mFileName.IsEmpty());
     MOZ_ASSERT(mBlob);
 
     AfterOppConnected();
 
     // Keep remote information
-    mRemoteObexVersion = data[3];
-    mRemoteConnectionFlags = data[4];
-    mRemoteMaxPacketLength = (static_cast<int>(data[5]) << 8) | data[6];
+    mRemoteObexVersion = aMessage->mData[3];
+    mRemoteConnectionFlags = aMessage->mData[4];
+    mRemoteMaxPacketLength =
+      (((int)(aMessage->mData[5]) << 8) | aMessage->mData[6]);
 
     // The length of file name exceeds maximum length.
     int fileNameByteLen = (mFileName.Length() + 1) * 2;
     int headerLen = kPutRequestHeaderSize + kPutRequestAppendHeaderSize;
     if (fileNameByteLen > mRemoteMaxPacketLength - headerLen) {
       BT_WARNING("The length of file name is aberrant.");
       SendDisconnectRequest();
       return;
@@ -1271,17 +1269,18 @@ void
 BluetoothOppManager::SendObexData(uint8_t* aData, uint8_t aOpcode, int aSize)
 {
   SetObexPacketInfo(aData, aOpcode, aSize);
 
   if (!mIsServer) {
     mLastCommand = aOpcode;
   }
 
-  UnixSocketRawData* s = new UnixSocketRawData(aData, aSize);
+  UnixSocketRawData* s = new UnixSocketRawData(aSize);
+  memcpy(s->mData, aData, s->mSize);
   mSocket->SendSocketData(s);
 }
 
 void
 BluetoothOppManager::FileTransferComplete()
 {
   if (mSendTransferCompleteFlag) {
     return;
--- a/dom/bluetooth2/bluedroid/BluetoothOppManager.cpp
+++ b/dom/bluetooth2/bluedroid/BluetoothOppManager.cpp
@@ -746,110 +746,107 @@ BluetoothOppManager::ValidateFileName()
 }
 
 bool
 BluetoothOppManager::ComposePacket(uint8_t aOpCode, UnixSocketRawData* aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aMessage);
 
-  const uint8_t* data = aMessage->GetData();
   int frameHeaderLength = 0;
 
   // See if this is the first part of each Put packet
   if (mPutPacketReceivedLength == 0) {
     // Section 3.3.3 "Put", IrOBEX 1.2
     // [opcode:1][length:2][Headers:var]
     frameHeaderLength = 3;
 
-    mPacketLength = ((static_cast<int>(data[1]) << 8) | data[2]) -
-                    frameHeaderLength;
-
+    mPacketLength = ((((int)aMessage->mData[1]) << 8) | aMessage->mData[2]) -
+                      frameHeaderLength;
     /**
      * A PUT request from remote devices may be divided into multiple parts.
      * In other words, one request may need to be received multiple times,
      * so here we keep a variable mPutPacketReceivedLength to indicate if
      * current PUT request is done.
      */
     mReceivedDataBuffer = new uint8_t[mPacketLength];
     mPutFinalFlag = (aOpCode == ObexRequestCode::PutFinal);
   }
 
-  int dataLength = aMessage->GetSize() - frameHeaderLength;
+  int dataLength = aMessage->mSize - frameHeaderLength;
 
   // Check length before memcpy to prevent from memory pollution
   if (dataLength < 0 ||
       mPutPacketReceivedLength + dataLength > mPacketLength) {
     BT_LOGR("Received packet size is unreasonable");
 
     ReplyToPut(mPutFinalFlag, false);
     DeleteReceivedFile();
     FileTransferComplete();
 
     return false;
   }
 
   memcpy(mReceivedDataBuffer.get() + mPutPacketReceivedLength,
-         &data[frameHeaderLength], dataLength);
+         &aMessage->mData[frameHeaderLength], dataLength);
 
   mPutPacketReceivedLength += dataLength;
 
   return (mPutPacketReceivedLength == mPacketLength);
 }
 
 void
 BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   uint8_t opCode;
-  int receivedLength = aMessage->GetSize();
-  const uint8_t* data = aMessage->GetData();
+  int receivedLength = aMessage->mSize;
 
   if (mPutPacketReceivedLength > 0) {
     opCode = mPutFinalFlag ? ObexRequestCode::PutFinal : ObexRequestCode::Put;
   } else {
-    opCode = data[0];
+    opCode = aMessage->mData[0];
 
     // When there's a Put packet right after a PutFinal packet,
     // which means it's the start point of a new file.
     if (mPutFinalFlag &&
         (opCode == ObexRequestCode::Put ||
          opCode == ObexRequestCode::PutFinal)) {
       mNewFileFlag = true;
       AfterFirstPut();
     }
   }
 
   ObexHeaderSet pktHeaders(opCode);
   if (opCode == ObexRequestCode::Connect) {
     // Section 3.3.1 "Connect", IrOBEX 1.2
     // [opcode:1][length:2][version:1][flags:1][MaxPktSizeWeCanReceive:2]
     // [Headers:var]
-    if (!ParseHeaders(&data[7], receivedLength - 7, &pktHeaders)) {
+    if (!ParseHeaders(&aMessage->mData[7], receivedLength - 7, &pktHeaders)) {
       ReplyError(ObexResponseCode::BadRequest);
       return;
     }
 
     ReplyToConnect();
     AfterOppConnected();
   } else if (opCode == ObexRequestCode::Abort) {
     // Section 3.3.5 "Abort", IrOBEX 1.2
     // [opcode:1][length:2][Headers:var]
-    if (!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
+    if (!ParseHeaders(&aMessage->mData[3], receivedLength - 3, &pktHeaders)) {
       ReplyError(ObexResponseCode::BadRequest);
       return;
     }
 
     ReplyToDisconnectOrAbort();
     DeleteReceivedFile();
   } else if (opCode == ObexRequestCode::Disconnect) {
     // Section 3.3.2 "Disconnect", IrOBEX 1.2
     // [opcode:1][length:2][Headers:var]
-    if (!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
+    if (!ParseHeaders(&aMessage->mData[3], receivedLength - 3, &pktHeaders)) {
       ReplyError(ObexResponseCode::BadRequest);
       return;
     }
 
     ReplyToDisconnectOrAbort();
     AfterOppDisconnected();
     FileTransferComplete();
   } else if (opCode == ObexRequestCode::Put ||
@@ -922,18 +919,17 @@ BluetoothOppManager::ServerDataHandler(U
   }
 }
 
 void
 BluetoothOppManager::ClientDataHandler(UnixSocketRawData* aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  const uint8_t* data = aMessage->GetData();
-  uint8_t opCode = data[0];
+  uint8_t opCode = aMessage->mData[0];
 
   // Check response code and send out system message as finished if the response
   // code is somehow incorrect.
   uint8_t expectedOpCode = ObexResponseCode::Success;
   if (mLastCommand == ObexRequestCode::Put) {
     expectedOpCode = ObexResponseCode::Continue;
   }
 
@@ -980,19 +976,20 @@ BluetoothOppManager::ClientDataHandler(U
     }
   } else if (mLastCommand == ObexRequestCode::Connect) {
     MOZ_ASSERT(!mFileName.IsEmpty());
     MOZ_ASSERT(mBlob);
 
     AfterOppConnected();
 
     // Keep remote information
-    mRemoteObexVersion = data[3];
-    mRemoteConnectionFlags = data[4];
-    mRemoteMaxPacketLength = ((static_cast<int>(data[5]) << 8) | data[6]);
+    mRemoteObexVersion = aMessage->mData[3];
+    mRemoteConnectionFlags = aMessage->mData[4];
+    mRemoteMaxPacketLength =
+      (((int)(aMessage->mData[5]) << 8) | aMessage->mData[6]);
 
     // The length of file name exceeds maximum length.
     int fileNameByteLen = (mFileName.Length() + 1) * 2;
     int headerLen = kPutRequestHeaderSize + kPutRequestAppendHeaderSize;
     if (fileNameByteLen > mRemoteMaxPacketLength - headerLen) {
       BT_WARNING("The length of file name is aberrant.");
       SendDisconnectRequest();
       return;
@@ -1251,17 +1248,18 @@ void
 BluetoothOppManager::SendObexData(uint8_t* aData, uint8_t aOpcode, int aSize)
 {
   SetObexPacketInfo(aData, aOpcode, aSize);
 
   if (!mIsServer) {
     mLastCommand = aOpcode;
   }
 
-  UnixSocketRawData* s = new UnixSocketRawData(aData, aSize);
+  UnixSocketRawData* s = new UnixSocketRawData(aSize);
+  memcpy(s->mData, aData, s->mSize);
   mSocket->SendSocketData(s);
 }
 
 void
 BluetoothOppManager::FileTransferComplete()
 {
   if (mSendTransferCompleteFlag) {
     return;
--- a/dom/bluetooth2/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth2/bluez/BluetoothHfpManager.cpp
@@ -702,18 +702,17 @@ BluetoothHfpManager::HandleShutdown()
 // Virtual function of class SocketConsumer
 void
 BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
                                        nsAutoPtr<UnixSocketRawData>& aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aSocket);
 
-  nsAutoCString msg(reinterpret_cast<const char*>(aMessage->GetData()),
-                    aMessage->GetSize());
+  nsAutoCString msg((const char*)aMessage->mData.get(), aMessage->mSize);
   msg.StripWhitespace();
 
   nsTArray<nsCString> atCommandValues;
 
   // For more information, please refer to 4.34.1 "Bluetooth Defined AT
   // Capabilities" in Bluetooth hands-free profile 1.6
   if (msg.Find("AT+BRSF=") != -1) {
 #ifdef MOZ_B2G_RIL
--- a/dom/bluetooth2/bluez/BluetoothOppManager.cpp
+++ b/dom/bluetooth2/bluez/BluetoothOppManager.cpp
@@ -769,108 +769,106 @@ BluetoothOppManager::ValidateFileName()
 
 bool
 BluetoothOppManager::ComposePacket(uint8_t aOpCode, UnixSocketRawData* aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aMessage);
 
   int frameHeaderLength = 0;
-  const uint8_t* data = aMessage->GetData();
 
   // See if this is the first part of each Put packet
   if (mPutPacketReceivedLength == 0) {
     // Section 3.3.3 "Put", IrOBEX 1.2
     // [opcode:1][length:2][Headers:var]
     frameHeaderLength = 3;
 
-    mPacketLength = ((static_cast<int>(data[1]) << 8) | data[2]) -
-                    frameHeaderLength;
+    mPacketLength = ((((int)aMessage->mData[1]) << 8) | aMessage->mData[2]) -
+                      frameHeaderLength;
     /**
      * A PUT request from remote devices may be divided into multiple parts.
      * In other words, one request may need to be received multiple times,
      * so here we keep a variable mPutPacketReceivedLength to indicate if
      * current PUT request is done.
      */
     mReceivedDataBuffer = new uint8_t[mPacketLength];
     mPutFinalFlag = (aOpCode == ObexRequestCode::PutFinal);
   }
 
-  int dataLength = aMessage->GetSize() - frameHeaderLength;
+  int dataLength = aMessage->mSize - frameHeaderLength;
 
   // Check length before memcpy to prevent from memory pollution
   if (dataLength < 0 ||
       mPutPacketReceivedLength + dataLength > mPacketLength) {
     BT_LOGR("Received packet size is unreasonable");
 
     ReplyToPut(mPutFinalFlag, false);
     DeleteReceivedFile();
     FileTransferComplete();
 
     return false;
   }
 
   memcpy(mReceivedDataBuffer.get() + mPutPacketReceivedLength,
-         &data[frameHeaderLength], dataLength);
+         &aMessage->mData[frameHeaderLength], dataLength);
 
   mPutPacketReceivedLength += dataLength;
 
   return (mPutPacketReceivedLength == mPacketLength);
 }
 
 void
 BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   uint8_t opCode;
-  int receivedLength = aMessage->GetSize();
-  const uint8_t* data = aMessage->GetData();
+  int receivedLength = aMessage->mSize;
 
   if (mPutPacketReceivedLength > 0) {
     opCode = mPutFinalFlag ? ObexRequestCode::PutFinal : ObexRequestCode::Put;
   } else {
-    opCode = data[0];
+    opCode = aMessage->mData[0];
 
     // When there's a Put packet right after a PutFinal packet,
     // which means it's the start point of a new file.
     if (mPutFinalFlag &&
         (opCode == ObexRequestCode::Put ||
          opCode == ObexRequestCode::PutFinal)) {
       mNewFileFlag = true;
       AfterFirstPut();
     }
   }
 
   ObexHeaderSet pktHeaders(opCode);
   if (opCode == ObexRequestCode::Connect) {
     // Section 3.3.1 "Connect", IrOBEX 1.2
     // [opcode:1][length:2][version:1][flags:1][MaxPktSizeWeCanReceive:2]
     // [Headers:var]
-    if (!ParseHeaders(&data[7], receivedLength - 7, &pktHeaders)) {
+    if (!ParseHeaders(&aMessage->mData[7], receivedLength - 7, &pktHeaders)) {
       ReplyError(ObexResponseCode::BadRequest);
       return;
     }
 
     ReplyToConnect();
     AfterOppConnected();
   } else if (opCode == ObexRequestCode::Abort) {
     // Section 3.3.5 "Abort", IrOBEX 1.2
     // [opcode:1][length:2][Headers:var]
-    if (!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
+    if (!ParseHeaders(&aMessage->mData[3], receivedLength - 3, &pktHeaders)) {
       ReplyError(ObexResponseCode::BadRequest);
       return;
     }
 
     ReplyToDisconnectOrAbort();
     DeleteReceivedFile();
   } else if (opCode == ObexRequestCode::Disconnect) {
     // Section 3.3.2 "Disconnect", IrOBEX 1.2
     // [opcode:1][length:2][Headers:var]
-    if (!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
+    if (!ParseHeaders(&aMessage->mData[3], receivedLength - 3, &pktHeaders)) {
       ReplyError(ObexResponseCode::BadRequest);
       return;
     }
 
     ReplyToDisconnectOrAbort();
     AfterOppDisconnected();
     FileTransferComplete();
   } else if (opCode == ObexRequestCode::Put ||
@@ -943,18 +941,17 @@ BluetoothOppManager::ServerDataHandler(U
   }
 }
 
 void
 BluetoothOppManager::ClientDataHandler(UnixSocketRawData* aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  const uint8_t* data = aMessage->GetData();
-  uint8_t opCode = data[0];
+  uint8_t opCode = aMessage->mData[0];
 
   // Check response code and send out system message as finished if the response
   // code is somehow incorrect.
   uint8_t expectedOpCode = ObexResponseCode::Success;
   if (mLastCommand == ObexRequestCode::Put) {
     expectedOpCode = ObexResponseCode::Continue;
   }
 
@@ -1001,19 +998,20 @@ BluetoothOppManager::ClientDataHandler(U
     }
   } else if (mLastCommand == ObexRequestCode::Connect) {
     MOZ_ASSERT(!mFileName.IsEmpty());
     MOZ_ASSERT(mBlob);
 
     AfterOppConnected();
 
     // Keep remote information
-    mRemoteObexVersion = data[3];
-    mRemoteConnectionFlags = data[4];
-    mRemoteMaxPacketLength = (static_cast<int>(data[5]) << 8) | data[6];
+    mRemoteObexVersion = aMessage->mData[3];
+    mRemoteConnectionFlags = aMessage->mData[4];
+    mRemoteMaxPacketLength =
+      (((int)(aMessage->mData[5]) << 8) | aMessage->mData[6]);
 
     // The length of file name exceeds maximum length.
     int fileNameByteLen = (mFileName.Length() + 1) * 2;
     int headerLen = kPutRequestHeaderSize + kPutRequestAppendHeaderSize;
     if (fileNameByteLen > mRemoteMaxPacketLength - headerLen) {
       BT_WARNING("The length of file name is aberrant.");
       SendDisconnectRequest();
       return;
@@ -1271,17 +1269,18 @@ void
 BluetoothOppManager::SendObexData(uint8_t* aData, uint8_t aOpcode, int aSize)
 {
   SetObexPacketInfo(aData, aOpcode, aSize);
 
   if (!mIsServer) {
     mLastCommand = aOpcode;
   }
 
-  UnixSocketRawData* s = new UnixSocketRawData(aData, aSize);
+  UnixSocketRawData* s = new UnixSocketRawData(aSize);
+  memcpy(s->mData, aData, s->mSize);
   mSocket->SendSocketData(s);
 }
 
 void
 BluetoothOppManager::FileTransferComplete()
 {
   if (mSendTransferCompleteFlag) {
     return;
--- a/dom/nfc/gonk/NfcService.cpp
+++ b/dom/nfc/gonk/NfcService.cpp
@@ -209,32 +209,36 @@ public:
   {
     MOZ_ASSERT(NS_IsMainThread());
   }
 
   NS_IMETHOD Run()
   {
     assertIsNfcServiceThread();
 
-    while (mData->GetSize()) {
+    size_t size = mData->mSize;
+    size_t offset = 0;
+
+    while (size > 0) {
       EventOptions event;
-      const uint8_t* data = mData->GetData();
-      uint32_t parcelSize = ((data[0] & 0xff) << 24) |
-                            ((data[1] & 0xff) << 16) |
-                            ((data[2] & 0xff) <<  8) |
-                             (data[3] & 0xff);
-      MOZ_ASSERT(parcelSize <= mData->GetSize());
+      const uint8_t* data = mData->mData.get();
+      uint32_t parcelSize = ((data[offset + 0] & 0xff) << 24) |
+                            ((data[offset + 1] & 0xff) << 16) |
+                            ((data[offset + 2] & 0xff) <<  8) |
+                             (data[offset + 3] & 0xff);
+      MOZ_ASSERT(parcelSize <= (mData->mSize - offset));
 
       Parcel parcel;
-      parcel.setData(mData->GetData(), parcelSize + sizeof(parcelSize));
+      parcel.setData(&data[offset], parcelSize + sizeof(int));
       mHandler->Unmarshall(parcel, event);
       nsCOMPtr<nsIRunnable> runnable = new NfcEventDispatcher(event);
       NS_DispatchToMainThread(runnable);
 
-      mData->Consume(parcelSize + sizeof(parcelSize));
+      size -= parcel.dataSize();
+      offset += parcel.dataSize();
     }
 
     return NS_OK;
   }
 
 private:
   NfcMessageHandler* mHandler;
   nsAutoPtr<UnixSocketRawData> mData;
--- a/ipc/keystore/KeyStore.cpp
+++ b/ipc/keystore/KeyStore.cpp
@@ -395,34 +395,35 @@ KeyStore::ResetHandlerInfo()
     mHandlerInfo.param[i].length = 0;
     memset(mHandlerInfo.param[i].data, 0, VALUE_SIZE);
   }
 }
 
 bool
 KeyStore::CheckSize(UnixSocketRawData *aMessage, size_t aExpectSize)
 {
-  return (aMessage->GetSize() >= aExpectSize);
+  return (aMessage->mSize - aMessage->mCurrentWriteOffset >= aExpectSize) ?
+         true : false;
 }
 
 ResponseCode
 KeyStore::ReadCommand(UnixSocketRawData *aMessage)
 {
   if (mHandlerInfo.state != STATE_IDLE) {
     NS_WARNING("Wrong state in ReadCommand()!");
     return SYSTEM_ERROR;
   }
 
   if (!CheckSize(aMessage, 1)) {
     NS_WARNING("Data size error in ReadCommand()!");
     return PROTOCOL_ERROR;
   }
 
-  mHandlerInfo.command = *aMessage->GetData();
-  aMessage->Consume(1);
+  mHandlerInfo.command = aMessage->mData[aMessage->mCurrentWriteOffset];
+  aMessage->mCurrentWriteOffset++;
 
   // Find corrsponding command pattern
   const struct ProtocolCommand *command = commands;
   while (command->command && command->command != mHandlerInfo.command) {
     command++;
   }
 
   if (!command->command) {
@@ -451,20 +452,19 @@ KeyStore::ReadLength(UnixSocketRawData *
   }
 
   if (!CheckSize(aMessage, 2)) {
     NS_WARNING("Data size error in ReadLength()!");
     return PROTOCOL_ERROR;
   }
 
   // Read length of command parameter.
-  // FIXME: Depends on endianess and (sizeof(unsigned short) == 2)
   unsigned short dataLength;
-  memcpy(&dataLength, aMessage->GetData(), 2);
-  aMessage->Consume(2);
+  memcpy(&dataLength, &aMessage->mData[aMessage->mCurrentWriteOffset], 2);
+  aMessage->mCurrentWriteOffset += 2;
   mHandlerInfo.param[mHandlerInfo.paramCount].length = ntohs(dataLength);
 
   mHandlerInfo.state = STATE_READ_PARAM_DATA;
 
   return SUCCESS;
 }
 
 ResponseCode
@@ -477,19 +477,19 @@ KeyStore::ReadData(UnixSocketRawData *aM
 
   if (!CheckSize(aMessage, mHandlerInfo.param[mHandlerInfo.paramCount].length)) {
     NS_WARNING("Data size error in ReadData()!");
     return PROTOCOL_ERROR;
   }
 
   // Read command parameter.
   memcpy(mHandlerInfo.param[mHandlerInfo.paramCount].data,
-         aMessage->GetData(),
+         &aMessage->mData[aMessage->mCurrentWriteOffset],
          mHandlerInfo.param[mHandlerInfo.paramCount].length);
-  aMessage->Consume(mHandlerInfo.param[mHandlerInfo.paramCount].length);
+  aMessage->mCurrentWriteOffset += mHandlerInfo.param[mHandlerInfo.paramCount].length;
   mHandlerInfo.paramCount++;
 
   if (mHandlerInfo.paramCount == mHandlerInfo.commandPattern->paramNum) {
     mHandlerInfo.state = STATE_PROCESSING;
   } else {
     mHandlerInfo.state = STATE_READ_PARAM_LEN;
   }
 
@@ -523,17 +523,17 @@ KeyStore::SendData(const uint8_t *aData,
 
 void
 KeyStore::ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // Handle request.
   ResponseCode result = SUCCESS;
-  while (aMessage->GetSize() ||
+  while (aMessage->mCurrentWriteOffset < aMessage->mSize ||
          mHandlerInfo.state == STATE_PROCESSING) {
     switch (mHandlerInfo.state) {
       case STATE_IDLE:
         result = ReadCommand(aMessage);
         break;
       case STATE_READ_PARAM_LEN:
         result = ReadLength(aMessage);
         break;
--- a/ipc/ril/Ril.cpp
+++ b/ipc/ril/Ril.cpp
@@ -179,23 +179,21 @@ private:
         nsAutoPtr<UnixSocketRawData> mMessage;
 };
 
 bool
 DispatchRILEvent::RunTask(JSContext *aCx)
 {
     JS::Rooted<JSObject*> obj(aCx, JS::CurrentGlobalOrNull(aCx));
 
-    JS::Rooted<JSObject*> array(aCx,
-                                JS_NewUint8Array(aCx, mMessage->GetSize()));
+    JS::Rooted<JSObject*> array(aCx, JS_NewUint8Array(aCx, mMessage->mSize));
     if (!array) {
         return false;
     }
-    memcpy(JS_GetArrayBufferViewData(array),
-           mMessage->GetData(), mMessage->GetSize());
+    memcpy(JS_GetArrayBufferViewData(array), mMessage->mData, mMessage->mSize);
 
     JS::AutoValueArray<2> args(aCx);
     args[0].setNumber((uint32_t)mClientId);
     args[1].setObject(*array);
 
     JS::Rooted<JS::Value> rval(aCx);
     return JS_CallFunctionName(aCx, obj, "onRILMessage", args, &rval);
 }
--- a/ipc/unixsocket/SocketBase.cpp
+++ b/ipc/unixsocket/SocketBase.cpp
@@ -2,104 +2,43 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 #include "SocketBase.h"
-#include <errno.h>
 #include <string.h>
-#include <unistd.h>
+#include "nsThreadUtils.h"
 
 namespace mozilla {
 namespace ipc {
 
 //
 // UnixSocketRawData
 //
 
+UnixSocketRawData::UnixSocketRawData(size_t aSize)
+: mSize(aSize)
+, mCurrentWriteOffset(0)
+{
+  mData = new uint8_t[mSize];
+}
+
 UnixSocketRawData::UnixSocketRawData(const void* aData, size_t aSize)
 : mSize(aSize)
-, mOffset(0)
-, mAvailableSpace(aSize)
+, mCurrentWriteOffset(0)
 {
   MOZ_ASSERT(aData || !mSize);
 
-  mData = new uint8_t[mAvailableSpace];
+  mData = new uint8_t[mSize];
   memcpy(mData, aData, mSize);
 }
 
-UnixSocketRawData::UnixSocketRawData(size_t aSize)
-: mSize(0)
-, mOffset(0)
-, mAvailableSpace(aSize)
-{
-  mData = new uint8_t[mAvailableSpace];
-}
-
-nsresult
-UnixSocketRawData::Receive(int aFd)
-{
-  if (!GetTrailingSpace()) {
-    if (!GetLeadingSpace()) {
-      return NS_ERROR_OUT_OF_MEMORY; /* buffer is full */
-    }
-    /* free up space at the end of data buffer */
-    if (GetSize() <= GetLeadingSpace()) {
-      memcpy(mData, GetData(), GetSize());
-    } else {
-      memmove(mData, GetData(), GetSize());
-    }
-    mOffset = 0;
-  }
-
-  ssize_t res =
-    TEMP_FAILURE_RETRY(read(aFd, GetTrailingBytes(), GetTrailingSpace()));
-
-  if (res < 0) {
-    if (errno == EAGAIN || errno == EWOULDBLOCK) {
-      return NS_OK; /* no more data available; try again later */
-    }
-    return NS_ERROR_FAILURE;
-  } else if (!res) {
-    /* EOF or peer shutdown sending */
-    return NS_OK;
-  }
-
-  mSize += res;
-
-  return NS_OK;
-}
-
-nsresult
-UnixSocketRawData::Send(int aFd)
-{
-  if (!GetSize()) {
-    return NS_OK;
-  }
-
-  ssize_t res = TEMP_FAILURE_RETRY(write(aFd, GetData(), GetSize()));
-
-  if (res < 0) {
-    if (errno == EAGAIN || errno == EWOULDBLOCK) {
-      return NS_OK; /* socket is blocked; try again later */
-    }
-    return NS_ERROR_FAILURE;
-  } else if (!res) {
-    /* nothing written */
-    return NS_OK;
-  }
-
-  Consume(res);
-
-  return NS_OK;
-}
-
 //
 // SocketConsumerBase
 //
 
 SocketConsumerBase::~SocketConsumerBase()
 {
   MOZ_ASSERT(mConnectionStatus == SOCKET_DISCONNECTED);
 }
@@ -190,17 +129,17 @@ SocketConsumerBase::SetConnectionStatus(
 //
 
 SocketIOBase::~SocketIOBase()
 { }
 
 void
 SocketIOBase::EnqueueData(UnixSocketRawData* aData)
 {
-  if (!aData->GetSize()) {
+  if (!aData->mSize) {
     delete aData; // delete empty data immediately
     return;
   }
   mOutgoingQ.AppendElement(aData);
 }
 
 bool
 SocketIOBase::HasPendingData() const
--- a/ipc/unixsocket/SocketBase.h
+++ b/ipc/unixsocket/SocketBase.h
@@ -4,16 +4,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 #ifndef mozilla_ipc_SocketBase_h
 #define mozilla_ipc_SocketBase_h
 
+#include <errno.h>
+#include <unistd.h>
 #include "base/message_loop.h"
 #include "nsAutoPtr.h"
 #include "nsTArray.h"
 #include "nsThreadUtils.h"
 
 #ifdef MOZ_TASK_TRACER
 #include "GeckoTaskTracer.h"
 using namespace mozilla::tasktracer;
@@ -24,74 +26,32 @@ namespace ipc {
 
 //
 // UnixSocketRawData
 //
 
 class UnixSocketRawData
 {
 public:
+  // Number of octets in mData.
+  size_t mSize;
+  size_t mCurrentWriteOffset;
+  nsAutoArrayPtr<uint8_t> mData;
 
-  /* This constructor copies aData of aSize bytes length into the
-   * new instance of |UnixSocketRawData|.
-   */
-  UnixSocketRawData(const void* aData, size_t aSize);
-
-  /* This constructor reserves aSize bytes of space. Currently
-   * it's only possible to fill this buffer by calling |Receive|.
+  /**
+   * Constructor for situations where only size is known beforehand
+   * (for example, when being assigned strings)
    */
   UnixSocketRawData(size_t aSize);
 
-  nsresult Receive(int aFd);
-  nsresult Send(int aFd);
-
-  const uint8_t* GetData() const
-  {
-    return mData + mOffset;
-  }
-
-  size_t GetSize() const
-  {
-    return mSize;
-  }
-
-  void Consume(size_t aSize)
-  {
-    MOZ_ASSERT(aSize <= mSize);
-
-    mSize -= aSize;
-    mOffset += aSize;
-  }
-
-protected:
-  size_t GetLeadingSpace() const
-  {
-    return mOffset;
-  }
-
-  size_t GetTrailingSpace() const
-  {
-    return mAvailableSpace - (mOffset + mSize);
-  }
-
-  size_t GetAvailableSpace() const
-  {
-    return mAvailableSpace;
-  }
-
-  void* GetTrailingBytes()
-  {
-    return mData + mOffset + mSize;
-  }
-
-private:
-  size_t mSize;
-  size_t mOffset;
-  size_t mAvailableSpace;
-  nsAutoArrayPtr<uint8_t> mData;
+  /**
+   * Constructor for situations where size and data is known
+   * beforehand (for example, when being assigned strings)
+   */
+  UnixSocketRawData(const void* aData, size_t aSize);
 };
 
 enum SocketConnectionStatus {
   SOCKET_DISCONNECTED = 0,
   SOCKET_LISTENING = 1,
   SOCKET_CONNECTING = 2,
   SOCKET_CONNECTED = 3
 };
@@ -363,67 +323,91 @@ public:
   bool HasPendingData() const;
 
   template <typename T>
   nsresult ReceiveData(int aFd, T* aIO)
   {
     MOZ_ASSERT(aFd >= 0);
     MOZ_ASSERT(aIO);
 
-    while (true) {
+    do {
       nsAutoPtr<UnixSocketRawData> incoming(
         new UnixSocketRawData(mMaxReadSize));
 
-      nsresult rv = incoming->Receive(aFd);
+      ssize_t res =
+        TEMP_FAILURE_RETRY(read(aFd, incoming->mData, incoming->mSize));
 
-      if (NS_WARN_IF(NS_FAILED(rv))) {
+      if (res < 0) {
+        if (errno == EAGAIN || errno == EWOULDBLOCK) {
+          return NS_OK; /* no more data available */
+        }
+        /* an error occored */
         nsRefPtr<nsRunnable> r = new SocketIORequestClosingRunnable<T>(aIO);
         NS_DispatchToMainThread(r);
-        return rv;
-      }
-      if (!incoming->GetSize()) {
-        /* no data available; try again later */
+        return NS_ERROR_FAILURE;
+      } else if (!res) {
+        /* EOF or peer shut down sending */
+        nsRefPtr<nsRunnable> r = new SocketIORequestClosingRunnable<T>(aIO);
+        NS_DispatchToMainThread(r);
         return NS_OK;
       }
 
 #ifdef MOZ_TASK_TRACER
       // Make unix socket creation events to be the source events of TaskTracer,
       // and originate the rest correlation tasks from here.
       AutoSourceEvent taskTracerEvent(SourceEventType::UNIXSOCKET);
 #endif
 
+      incoming->mSize = res;
       nsRefPtr<nsRunnable> r =
         new SocketIOReceiveRunnable<T>(aIO, incoming.forget());
       NS_DispatchToMainThread(r);
-    }
+    } while (true);
 
     return NS_OK;
   }
 
   template <typename T>
   nsresult SendPendingData(int aFd, T* aIO)
   {
     MOZ_ASSERT(aFd >= 0);
     MOZ_ASSERT(aIO);
 
-    while (HasPendingData()) {
+    do {
+      if (!HasPendingData()) {
+        return NS_OK;
+      }
+
       UnixSocketRawData* outgoing = mOutgoingQ.ElementAt(0);
+      MOZ_ASSERT(outgoing->mSize);
 
-      nsresult rv = outgoing->Send(aFd);
+      const uint8_t* data = outgoing->mData + outgoing->mCurrentWriteOffset;
+      size_t size = outgoing->mSize - outgoing->mCurrentWriteOffset;
+
+      ssize_t res = TEMP_FAILURE_RETRY(write(aFd, data, size));
 
-      if (NS_WARN_IF(NS_FAILED(rv))) {
+      if (res < 0) {
+        if (errno == EAGAIN || errno == EWOULDBLOCK) {
+          return NS_OK; /* no more data available */
+        }
+        /* an error occored */
         nsRefPtr<nsRunnable> r = new SocketIORequestClosingRunnable<T>(aIO);
         NS_DispatchToMainThread(r);
-        return rv;
+        return NS_ERROR_FAILURE;
+      } else if (!res) {
+        return NS_OK; /* nothing written */
       }
-      if (!outgoing->GetSize()) {
+
+      outgoing->mCurrentWriteOffset += res;
+
+      if (outgoing->mCurrentWriteOffset == outgoing->mSize) {
         mOutgoingQ.RemoveElementAt(0);
         delete outgoing;
       }
-    }
+    } while (true);
 
     return NS_OK;
   }
 
 protected:
   SocketIOBase(size_t aMaxReadSize);
 
 private: