Modified: trunk/Source/WebKit2/Platform/CoreIPC/unix/ConnectionUnix.cpp (88146 => 88147)
--- trunk/Source/WebKit2/Platform/CoreIPC/unix/ConnectionUnix.cpp 2011-06-06 08:09:17 UTC (rev 88146)
+++ trunk/Source/WebKit2/Platform/CoreIPC/unix/ConnectionUnix.cpp 2011-06-06 08:35:50 UTC (rev 88147)
@@ -93,7 +93,9 @@
{
m_socketDescriptor = identifier;
m_readBuffer.resize(messageMaxSize);
- m_currentMessageSize = 0;
+ m_readBufferSize = 0;
+ m_fileDescriptors.resize(attachmentMaxAmount);
+ m_fileDescriptorsSize = 0;
#if PLATFORM(QT)
m_socketNotifier = 0;
@@ -157,116 +159,181 @@
T& m_attachments;
};
-void Connection::readyReadHandler()
+bool Connection::processMessage()
{
+ if (m_readBufferSize < sizeof(MessageInfo))
+ return false;
+
+ uint8_t* messageData = m_readBuffer.data();
+ MessageInfo messageInfo;
+ memcpy(&messageInfo, messageData, sizeof(messageInfo));
+ messageData += sizeof(messageInfo);
+
+ size_t messageLength = sizeof(MessageInfo) + messageInfo.attachmentCount() * sizeof(size_t) + (messageInfo.isMessageBodyOOL() ? 0 : messageInfo.bodySize());
+ if (m_readBufferSize < messageLength)
+ return false;
+
Deque<Attachment> attachments;
-#if PLATFORM(QT)
- SocketNotifierResourceGuard socketNotifierEnabler(m_socketNotifier);
-#endif
AttachmentResourceGuard<Deque<Attachment>, Deque<Attachment>::iterator> attachementDisposer(attachments);
+ RefPtr<WebKit::SharedMemory> oolMessageBody;
- OwnArrayPtr<char> attachmentDescriptorBuffer = adoptArrayPtr(new char[CMSG_SPACE(sizeof(int) * (attachmentMaxAmount))]);
- struct msghdr message;
- memset(&message, 0, sizeof(message));
+ int attachmentCount = messageInfo.attachmentCount();
+ if (attachmentCount) {
+ OwnArrayPtr<size_t> attachmentSizes = adoptArrayPtr(new size_t[attachmentCount]);
+ memcpy(attachmentSizes.get(), messageData, sizeof(size_t) * attachmentCount);
+ messageData += sizeof(size_t) * attachmentCount;
- struct iovec iov[1];
- memset(&iov, 0, sizeof(iov));
+ if (messageInfo.isMessageBodyOOL())
+ attachmentCount--;
- message.msg_control = attachmentDescriptorBuffer.get();
- message.msg_controllen = CMSG_SPACE(sizeof(int) * (attachmentMaxAmount));
+ for (int i = 0; i < attachmentCount; ++i)
+ attachments.append(Attachment(m_fileDescriptors[i], attachmentSizes[i]));
- iov[0].iov_base = m_readBuffer.data();
- iov[0].iov_len = m_readBuffer.size();
+ if (messageInfo.isMessageBodyOOL()) {
+ ASSERT(messageInfo.bodySize());
- message.msg_iov = iov;
- message.msg_iovlen = 1;
+ WebKit::SharedMemory::Handle handle;
+ handle.adoptFromAttachment(m_fileDescriptors[attachmentCount], attachmentSizes[attachmentCount]);
+ if (handle.isNull()) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
-
- int messageLength = 0;
- while ((messageLength = recvmsg(m_socketDescriptor, &message, 0)) == -1) {
- if (errno != EINTR)
- return;
+ oolMessageBody = WebKit::SharedMemory::create(handle, WebKit::SharedMemory::ReadOnly);
+ if (!oolMessageBody) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+ }
}
- struct cmsghdr* controlMessage = CMSG_FIRSTHDR(&message);
+ ASSERT(attachments.size() == messageInfo.isMessageBodyOOL() ? messageInfo.attachmentCount() - 1 : messageInfo.attachmentCount());
- MessageInfo messageInfo;
- unsigned char* messageData = m_readBuffer.data();
+ uint8_t* messageBody = messageData;
+ if (messageInfo.isMessageBodyOOL())
+ messageBody = reinterpret_cast<uint8_t*>(oolMessageBody->data());
- memcpy(&messageInfo, messageData, sizeof(messageInfo));
- ASSERT(messageLength == sizeof(messageInfo) + messageInfo.attachmentCount() * sizeof(size_t) + (messageInfo.isMessageBodyOOL() ? 0 : messageInfo.bodySize()));
+ ArgumentDecoder* argumentDecoder;
+ if (attachments.isEmpty())
+ argumentDecoder = new ArgumentDecoder(messageBody, messageInfo.bodySize());
+ else
+ argumentDecoder = new ArgumentDecoder(messageBody, messageInfo.bodySize(), attachments);
- messageData += sizeof(messageInfo);
+ processIncomingMessage(messageInfo.messageID(), adoptPtr(argumentDecoder));
- RefPtr<WebKit::SharedMemory> oolMessageBody;
+ if (m_readBufferSize > messageLength) {
+ memmove(m_readBuffer.data(), m_readBuffer.data() + messageLength, m_readBufferSize - messageLength);
+ m_readBufferSize -= messageLength;
+ } else
+ m_readBufferSize = 0;
if (messageInfo.attachmentCount()) {
- if (controlMessage && controlMessage->cmsg_level == SOL_SOCKET && controlMessage->cmsg_type == SCM_RIGHTS) {
- OwnArrayPtr<size_t> attachmentSizes = adoptArrayPtr(new size_t[messageInfo.attachmentCount()]);
- memcpy(attachmentSizes.get(), messageData, sizeof(size_t) * messageInfo.attachmentCount());
+ if (m_fileDescriptorsSize > messageInfo.attachmentCount()) {
+ size_t fileDescriptorsLength = messageInfo.attachmentCount() * sizeof(int);
+ memmove(m_fileDescriptors.data(), m_fileDescriptors.data() + fileDescriptorsLength, m_fileDescriptorsSize - fileDescriptorsLength);
+ m_fileDescriptorsSize -= fileDescriptorsLength;
+ } else
+ m_fileDescriptorsSize = 0;
+ }
- messageData += sizeof(attachmentSizes);
- OwnArrayPtr<int> fileDescriptors = adoptArrayPtr(new int[messageInfo.attachmentCount()]);
- memcpy(fileDescriptors.get(), CMSG_DATA(controlMessage), sizeof(int) * messageInfo.attachmentCount());
+ return true;
+}
- int attachmentCount = messageInfo.attachmentCount();
+static ssize_t readBytesFromSocket(int socketDescriptor, uint8_t* buffer, int count, int* fileDescriptors, size_t* fileDescriptorsCount)
+{
+ struct msghdr message;
+ memset(&message, 0, sizeof(message));
- if (messageInfo.isMessageBodyOOL())
- attachmentCount--;
+ struct iovec iov[1];
+ memset(&iov, 0, sizeof(iov));
- for (int i = 0; i < attachmentCount; ++i) {
- while (fcntl(fileDescriptors[i], F_SETFL, FD_CLOEXEC) == -1) {
- if (errno != EINTR) {
- ASSERT_NOT_REACHED();
- return;
- }
- }
- }
+ message.msg_controllen = CMSG_SPACE(sizeof(int) * attachmentMaxAmount);
+ OwnArrayPtr<char> attachmentDescriptorBuffer = adoptArrayPtr(new char[message.msg_controllen]);
+ memset(attachmentDescriptorBuffer.get(), 0, message.msg_controllen);
+ message.msg_control = attachmentDescriptorBuffer.get();
- for (int i = 0; i < attachmentCount; ++i)
- attachments.append(Attachment(fileDescriptors[i], attachmentSizes[i]));
+ iov[0].iov_base = buffer;
+ iov[0].iov_len = count;
- if (messageInfo.isMessageBodyOOL()) {
- ASSERT(messageInfo.bodySize());
+ message.msg_iov = iov;
+ message.msg_iovlen = 1;
- WebKit::SharedMemory::Handle handle;
- handle.adoptFromAttachment(fileDescriptors[attachmentCount], attachmentSizes[attachmentCount]);
- if (handle.isNull()) {
- ASSERT_NOT_REACHED();
- return;
+ while (true) {
+ ssize_t bytesRead = recvmsg(socketDescriptor, &message, 0);
+
+ if (bytesRead < 0) {
+ if (errno == EINTR)
+ continue;
+
+ return -1;
+ }
+
+ bool found = false;
+ struct cmsghdr* controlMessage;
+ for (controlMessage = CMSG_FIRSTHDR(&message); controlMessage; controlMessage = CMSG_NXTHDR(&message, controlMessage)) {
+ if (controlMessage->cmsg_level == SOL_SOCKET && controlMessage->cmsg_type == SCM_RIGHTS) {
+ *fileDescriptorsCount = (controlMessage->cmsg_len - CMSG_LEN(0)) / sizeof(int);
+ memcpy(fileDescriptors, CMSG_DATA(controlMessage), sizeof(int) * *fileDescriptorsCount);
+
+ for (size_t i = 0; i < *fileDescriptorsCount; ++i) {
+ while (fcntl(fileDescriptors[i], F_SETFL, FD_CLOEXEC) == -1) {
+ if (errno != EINTR) {
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ }
}
- oolMessageBody = WebKit::SharedMemory::create(handle, WebKit::SharedMemory::ReadOnly);
- if (!oolMessageBody) {
- ASSERT_NOT_REACHED();
- return;
- }
+ found = true;
+ break;
}
+ }
- controlMessage = CMSG_NXTHDR(&message, controlMessage);
- } else {
- ASSERT_NOT_REACHED();
- return;
- }
+ if (!found)
+ *fileDescriptorsCount = 0;
+
+ return bytesRead;
}
- ASSERT(attachments.size() == messageInfo.isMessageBodyOOL() ? messageInfo.attachmentCount() - 1 : messageInfo.attachmentCount());
+ return -1;
+}
- unsigned char* messageBody = messageData;
+void Connection::readyReadHandler()
+{
+#if PLATFORM(QT)
+ SocketNotifierResourceGuard socketNotifierEnabler(m_socketNotifier);
+#endif
- if (messageInfo.isMessageBodyOOL())
- messageBody = reinterpret_cast<unsigned char*>(oolMessageBody->data());
+ while (true) {
+ size_t fileDescriptorsCount = 0;
+ size_t bytesToRead = m_readBuffer.size() - m_readBufferSize;
+ ssize_t bytesRead = readBytesFromSocket(m_socketDescriptor, m_readBuffer.data() + m_readBufferSize, bytesToRead,
+ m_fileDescriptors.data() + m_fileDescriptorsSize, &fileDescriptorsCount);
- ArgumentDecoder* argumentDecoder;
- if (attachments.isEmpty())
- argumentDecoder = new ArgumentDecoder(messageBody, messageInfo.bodySize());
- else
- argumentDecoder = new ArgumentDecoder(messageBody, messageInfo.bodySize(), attachments);
+ if (bytesRead < 0) {
+ // EINTR was already handled by readBytesFromSocket.
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ return;
- processIncomingMessage(messageInfo.messageID(), adoptPtr(argumentDecoder));
+ // FIXME: Handle other errors here?
+ return;
+ }
- ASSERT(!controlMessage);
+ m_readBufferSize += bytesRead;
+ m_fileDescriptorsSize += fileDescriptorsCount;
+
+ if (!bytesRead) {
+ connectionDidClose();
+ return;
+ }
+
+ // Process messages from data received.
+ while (true) {
+ if (!processMessage())
+ break;
+ }
+ }
}
bool Connection::open()
Modified: trunk/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp (88146 => 88147)
--- trunk/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp 2011-06-06 08:09:17 UTC (rev 88146)
+++ trunk/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp 2011-06-06 08:35:50 UTC (rev 88147)
@@ -61,7 +61,7 @@
GPid pid = 0;
int sockets[2];
- if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) < 0) {
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) {
g_printerr("Creation of socket failed: %s.\n", g_strerror(errno));
ASSERT_NOT_REACHED();
return;