Changeset 76507 in webkit
- Timestamp:
- Jan 24, 2011 4:58:32 AM (13 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 2 deleted
- 19 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r76496 r76507 1 2011-01-24 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com> 2 3 Reviewed by Kenneth Rohde Christiansen. 4 5 [Qt] Remove CleanupHandler by passing file descriptors. 6 7 Deleting files in signal handler of UI process is not a good idea, 8 because the memory where filenames are stored might not be valid 9 after a crash. 10 11 To avoid the need of using signal handlers for cleanup, 12 change following: 13 1) Avoid passing filenames between processes, pass fds 14 2) When mmap'ing files, delete them immediately after 15 opening and mmap'ing them. 16 3) Pass sockets with fds during fork+exec instead of 17 passing them via the filesystem. 18 4) Use mmap'ed files for implementation of SharedMemory. 19 QSharedMemory does not support cleanup correctly. 20 21 Consquences: 22 - Move MappedMemory to SharedMemory, make UpdateChunk use this. 23 - Implement CoreIPC::Attachment using mmaped files. 24 - Send messages using datagram socket. This solution works 25 similiarly to Mach ports on Mac. 26 - Send big messages out-of-line and thus avoid increasing 27 the receive buffer. 28 - Remove MemoryMappedPool and rely on libc/kernel caching 29 of mmapped areas. 30 - Unmap memory areas after use. 31 - When UI process crashes, kill the web process using SIGKILL. 32 This is possible again because cleanup handler is not needed. 33 34 [WK2][Qt] Multiple problems with MemoryMappedPool 35 https://bugs.webkit.org/show_bug.cgi?id=51984 36 37 * Platform/CoreIPC/Attachment.cpp: 38 (CoreIPC::Attachment::Attachment): 39 * Platform/CoreIPC/Attachment.h: 40 (CoreIPC::Attachment::size): 41 (CoreIPC::Attachment::releaseFileDescriptor): 42 (CoreIPC::Attachment::fileDescriptor): 43 * Platform/CoreIPC/Connection.h: 44 * Platform/CoreIPC/qt/ConnectionQt.cpp: 45 (CoreIPC::MessageInfo::MessageInfo): 46 (CoreIPC::MessageInfo::setMessageBodyOOL): 47 (CoreIPC::MessageInfo::isMessageBodyOOL): 48 (CoreIPC::MessageInfo::bodySize): 49 (CoreIPC::MessageInfo::messageID): 50 (CoreIPC::MessageInfo::attachmentCount): 51 (CoreIPC::Connection::platformInitialize): 52 (CoreIPC::Connection::platformInvalidate): 53 (CoreIPC::SocketNotifierDisableGuard::SocketNotifierDisableGuard): 54 (CoreIPC::SocketNotifierDisableGuard::~SocketNotifierDisableGuard): 55 (CoreIPC::Connection::readyReadHandler): 56 (CoreIPC::Connection::open): 57 (CoreIPC::Connection::platformCanSendOutgoingMessages): 58 (CoreIPC::Connection::sendOutgoingMessage): 59 * Platform/SharedMemory.h: 60 * Platform/WorkQueue.h: 61 * Platform/qt/MappedMemoryPool.cpp: Removed. 62 * Platform/qt/MappedMemoryPool.h: Removed. 63 * Platform/qt/SharedMemoryQt.cpp: 64 (WebKit::SharedMemory::Handle::Handle): 65 (WebKit::SharedMemory::Handle::~Handle): 66 (WebKit::SharedMemory::Handle::isNull): 67 (WebKit::SharedMemory::Handle::encode): 68 (WebKit::SharedMemory::Handle::decode): 69 (WebKit::SharedMemory::Handle::releaseToAttachment): 70 (WebKit::SharedMemory::Handle::adoptFromAttachment): 71 (WebKit::SharedMemory::create): 72 (WebKit::accessModeMMap): 73 (WebKit::SharedMemory::~SharedMemory): 74 (WebKit::accessModeFile): 75 (WebKit::SharedMemory::createHandle): 76 * Platform/qt/WorkQueueQt.cpp: 77 (WorkQueue::registerSocketEventHandler): 78 * Shared/qt/UpdateChunk.cpp: 79 (WebKit::UpdateChunk::UpdateChunk): 80 (WebKit::UpdateChunk::~UpdateChunk): 81 (WebKit::UpdateChunk::encode): 82 (WebKit::UpdateChunk::decode): 83 (WebKit::UpdateChunk::createImage): 84 * Shared/qt/UpdateChunk.h: 85 * UIProcess/Launcher/ProcessLauncher.h: 86 * UIProcess/Launcher/qt/ProcessLauncherQt.cpp: 87 (WebKit::QtWebProcess::QtWebProcess): 88 (WebKit::QtWebProcess::setupChildProcess): 89 (WebKit::ProcessLauncher::launchProcess): 90 (WebKit::ProcessLauncher::platformInvalidate): 91 * UIProcess/Launcher/qt/ThreadLauncherQt.cpp: 92 (WebKit::webThreadBody): 93 (WebKit::ThreadLauncher::createWebThread): 94 * WebKit2.pro: 95 * WebProcess/qt/WebProcessMainQt.cpp: 96 (WebKit::WebProcessMainQt): 97 1 98 2011-01-24 Andras Becsi <abecsi@webkit.org> 2 99 -
trunk/Source/WebKit2/Platform/CoreIPC/ArgumentDecoder.cpp
r68686 r76507 47 47 ASSERT(m_buffer); 48 48 fastFree(m_buffer); 49 #if !PLATFORM(QT) 49 50 // FIXME: We need to dispose of the mach ports in cases of failure. 51 #else 52 Deque<Attachment>::iterator end = m_attachments.end(); 53 for (Deque<Attachment>::iterator it = m_attachments.begin(); it != end; ++it) 54 it->dispose(); 55 #endif 50 56 } 51 57 -
trunk/Source/WebKit2/Platform/CoreIPC/ArgumentEncoder.cpp
r71931 r76507 50 50 if (m_buffer) 51 51 fastFree(m_buffer); 52 #if !PLATFORM(QT) 52 53 // FIXME: We need to dispose of the attachments in cases of failure. 54 #else 55 for (int i = 0; i < m_attachments.size(); ++i) 56 m_attachments[i].dispose(); 57 #endif 53 58 } 54 59 -
trunk/Source/WebKit2/Platform/CoreIPC/Attachment.h
r64877 r76507 41 41 MachPortType, 42 42 MachOOLMemoryType 43 #elif PLATFORM(QT) 44 MappedMemory 43 45 #endif 44 46 }; … … 47 49 Attachment(mach_port_name_t port, mach_msg_type_name_t disposition); 48 50 Attachment(void* address, mach_msg_size_t size, mach_msg_copy_options_t copyOptions, bool deallocate); 51 #elif PLATFORM(QT) 52 Attachment(int fileDescriptor, size_t); 49 53 #endif 50 54 … … 63 67 mach_msg_copy_options_t copyOptions() const { ASSERT(m_type == MachOOLMemoryType); return m_oolMemory.copyOptions; } 64 68 bool deallocate() const { ASSERT(m_type == MachOOLMemoryType); return m_oolMemory.deallocate; } 69 #elif PLATFORM(QT) 70 size_t size() const { return m_size; } 71 72 int releaseFileDescriptor() { int temp = m_fileDescriptor; m_fileDescriptor = -1; return temp; } 73 int fileDescriptor() const { return m_fileDescriptor; } 74 75 void dispose(); 65 76 #endif 66 77 … … 84 95 } m_oolMemory; 85 96 }; 97 #elif PLATFORM(QT) 98 int m_fileDescriptor; 99 size_t m_size; 86 100 #endif 87 101 }; -
trunk/Source/WebKit2/Platform/CoreIPC/Connection.h
r76280 r76507 45 45 #include <string> 46 46 #elif PLATFORM(QT) 47 #include <QString> 48 class QLocalServer; 49 class QLocalSocket; 47 class QSocketNotifier; 48 #include "PlatformProcessIdentifier.h" 50 49 #endif 51 50 … … 99 98 static bool createServerAndClientIdentifiers(Identifier& serverIdentifier, Identifier& clientIdentifier); 100 99 #elif PLATFORM(QT) 101 typedef const QStringIdentifier;100 typedef int Identifier; 102 101 #elif PLATFORM(GTK) 103 102 typedef int Identifier; … … 110 109 #if PLATFORM(MAC) 111 110 void setShouldCloseConnectionOnMachExceptions(); 111 #elif PLATFORM(QT) 112 void setShouldCloseConnectionOnProcessTermination(WebKit::PlatformProcessIdentifier); 112 113 #endif 113 114 … … 286 287 Vector<uint8_t> m_readBuffer; 287 288 size_t m_currentMessageSize; 288 Q LocalSocket* m_socket;289 QString m_serverName;289 QSocketNotifier* m_socketNotifier; 290 int m_socketDescriptor; 290 291 #elif PLATFORM(GTK) 291 292 void readEventHandler(); -
trunk/Source/WebKit2/Platform/CoreIPC/qt/AttachmentQt.cpp
r76506 r76507 1 1 /* 2 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2010 University of Szeged3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) 4 4 * 5 5 * Redistribution and use in source and binary forms, with or without … … 12 12 * documentation and/or other materials provided with the distribution. 13 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 15 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR … … 25 25 */ 26 26 27 #include "WebContext.h" 27 #include "Attachment.h" 28 #if PLATFORM(QT) 29 #include <unistd.h> 30 #include <errno.h> 31 #endif 28 32 29 #include "ApplicationCacheStorage.h"30 #include "WebProcessCreationParameters.h"31 33 32 namespace WebKit{34 namespace CoreIPC { 33 35 34 String WebContext::applicationCacheDirectory() 36 Attachment::Attachment(int fileDescriptor, size_t size) 37 : m_type(MappedMemory) 38 , m_fileDescriptor(fileDescriptor) 39 , m_size(size) 35 40 { 36 #if ENABLE(OFFLINE_WEB_APPLICATIONS) 37 return WebCore::cacheStorage().cacheDirectory(); 38 #else 39 return QString(); 40 #endif 41 ASSERT(m_fileDescriptor); 42 ASSERT(m_size); 41 43 } 42 44 43 void WebContext::platformInitializeWebProcess(WebProcessCreationParameters&)45 void Attachment::dispose() 44 46 { 47 if (m_fileDescriptor != -1) 48 while (close(m_fileDescriptor) == -1 && (errno == EINTR)) { } 45 49 } 46 50 47 } // namespace WebKit51 } // namespace CoreIPC -
trunk/Source/WebKit2/Platform/CoreIPC/qt/ConnectionQt.cpp
r74967 r76507 30 30 #include "ProcessLauncher.h" 31 31 #include "WorkItem.h" 32 #include "SharedMemory.h" 33 #include "WebProcessProxy.h" 32 34 #include <QApplication> 33 #include <QLocalServer> 34 #include <QLocalSocket> 35 #include <QSocketNotifier> 36 #include <sys/socket.h> 37 #include <unistd.h> 38 #include <errno.h> 39 #include <fcntl.h> 40 #include <wtf/Assertions.h> 35 41 36 42 using namespace std; … … 38 44 namespace CoreIPC { 39 45 40 // This is what other ports use...41 46 static const size_t messageMaxSize = 4096; 47 static const size_t attachmentMaxAmount = 255; 48 49 enum { 50 MessageBodyIsOOL = 1 << 31 51 }; 52 53 class MessageInfo { 54 public: 55 MessageInfo() { } 56 57 MessageInfo(MessageID messageID, size_t bodySize, size_t initialAttachmentCount) 58 : m_messageID(messageID.toInt()) 59 , m_bodySize(bodySize) 60 , m_attachmentCount(initialAttachmentCount) 61 { 62 ASSERT(!(m_messageID & MessageBodyIsOOL)); 63 } 64 65 void setMessageBodyOOL() 66 { 67 ASSERT(!isMessageBodyOOL()); 68 69 m_messageID |= MessageBodyIsOOL; 70 m_attachmentCount++; 71 } 72 73 bool isMessageBodyOOL() const { return m_messageID & MessageBodyIsOOL; } 74 75 size_t bodySize() const { return m_bodySize; } 76 77 MessageID messageID() const { return MessageID::fromInt(m_messageID & ~MessageBodyIsOOL); } 78 79 size_t attachmentCount() const { return m_attachmentCount; } 80 81 private: 82 uint32_t m_messageID; 83 size_t m_bodySize; 84 size_t m_attachmentCount; 85 }; 42 86 43 87 void Connection::platformInitialize(Identifier identifier) 44 88 { 45 m_s erverName= identifier;46 m_socket = 0;89 m_socketDescriptor = identifier; 90 m_socketNotifier = 0; 47 91 m_readBuffer.resize(messageMaxSize); 48 92 m_currentMessageSize = 0; … … 51 95 void Connection::platformInvalidate() 52 96 { 53 m_socket->disconnect(); 54 if (!m_isServer) 55 m_socket->deleteLater(); 56 m_socket = 0; 57 } 97 if (m_socketDescriptor != -1) 98 while (close(m_socketDescriptor) == -1 && errno == EINTR) { } 99 100 if (!m_isConnected) 101 return; 102 103 delete m_socketNotifier; 104 m_socketNotifier = 0; 105 m_socketDescriptor = -1; 106 m_isConnected = false; 107 } 108 109 class SocketNotifierResourceGuard { 110 public: 111 SocketNotifierResourceGuard(QSocketNotifier* socketNotifier) 112 : m_socketNotifier(socketNotifier) 113 { 114 m_socketNotifier->setEnabled(false); 115 } 116 117 ~SocketNotifierResourceGuard() 118 { 119 m_socketNotifier->setEnabled(true); 120 } 121 122 private: 123 QSocketNotifier* const m_socketNotifier; 124 }; 125 126 template<class T, class iterator> 127 class AttachmentResourceGuard { 128 public: 129 AttachmentResourceGuard(T& attachments) 130 : m_attachments(attachments) 131 { 132 } 133 ~AttachmentResourceGuard() 134 { 135 iterator end = m_attachments.end(); 136 for (iterator i = m_attachments.begin(); i != end; ++i) 137 i->dispose(); 138 } 139 private: 140 T& m_attachments; 141 }; 58 142 59 143 void Connection::readyReadHandler() 60 144 { 61 while (m_socket->bytesAvailable()) { 62 if (!m_currentMessageSize) { 63 size_t numberOfBytesRead = m_socket->read(reinterpret_cast<char*>(m_readBuffer.data()), sizeof(size_t)); 64 ASSERT_UNUSED(numberOfBytesRead, numberOfBytesRead); 65 m_currentMessageSize = *reinterpret_cast<size_t*>(m_readBuffer.data()); 145 Deque<Attachment> attachments; 146 SocketNotifierResourceGuard socketNotifierEnabler(m_socketNotifier); 147 AttachmentResourceGuard<Deque<Attachment>, Deque<Attachment>::iterator> attachementDisposer(attachments); 148 149 char attachmentDescriptorBuffer[CMSG_SPACE(sizeof(int) * (attachmentMaxAmount))]; 150 struct msghdr message; 151 memset(&message, 0, sizeof(message)); 152 153 struct iovec iov[1]; 154 memset(&iov, 0, sizeof(iov)); 155 156 message.msg_control = attachmentDescriptorBuffer; 157 message.msg_controllen = CMSG_SPACE(sizeof(int) * (attachmentMaxAmount)); 158 159 iov[0].iov_base = m_readBuffer.data(); 160 iov[0].iov_len = m_readBuffer.size(); 161 162 message.msg_iov = iov; 163 message.msg_iovlen = 1; 164 165 166 int messageLength = 0; 167 while ((messageLength = recvmsg(m_socketDescriptor, &message, MSG_CMSG_CLOEXEC)) == -1) { 168 if (errno != EINTR) 169 return; 170 } 171 172 struct cmsghdr* controlMessage = CMSG_FIRSTHDR(&message); 173 174 MessageInfo messageInfo; 175 unsigned char* messageData = m_readBuffer.data(); 176 177 memcpy(&messageInfo, messageData, sizeof(messageInfo)); 178 ASSERT(messageLength == sizeof(messageInfo) + messageInfo.attachmentCount() * sizeof(size_t) + (messageInfo.isMessageBodyOOL() ? 0 : messageInfo.bodySize())); 179 180 messageData += sizeof(messageInfo); 181 182 RefPtr<WebKit::SharedMemory> oolMessageBody; 183 184 if (messageInfo.attachmentCount()) { 185 if (controlMessage && controlMessage->cmsg_level == SOL_SOCKET && controlMessage->cmsg_type == SCM_RIGHTS) { 186 size_t attachmentSizes[messageInfo.attachmentCount()]; 187 memcpy(attachmentSizes, messageData, sizeof(attachmentSizes)); 188 189 messageData += sizeof(attachmentSizes); 190 191 int fileDescriptors[messageInfo.attachmentCount()]; 192 memcpy(fileDescriptors, CMSG_DATA(controlMessage), sizeof(fileDescriptors)); 193 194 int attachmentCount = messageInfo.attachmentCount(); 195 196 if (messageInfo.isMessageBodyOOL()) 197 attachmentCount--; 198 199 for (int i = 0; i < attachmentCount; ++i) 200 attachments.append(Attachment(fileDescriptors[i], attachmentSizes[i])); 201 202 if (messageInfo.isMessageBodyOOL()) { 203 ASSERT(messageInfo.bodySize()); 204 205 WebKit::SharedMemory::Handle handle; 206 handle.adoptFromAttachment(fileDescriptors[attachmentCount], attachmentSizes[attachmentCount]); 207 if (handle.isNull()) { 208 ASSERT_NOT_REACHED(); 209 return; 210 } 211 212 oolMessageBody = WebKit::SharedMemory::create(handle, WebKit::SharedMemory::ReadOnly); 213 if (!oolMessageBody) { 214 ASSERT_NOT_REACHED(); 215 return; 216 } 217 } 218 219 controlMessage = CMSG_NXTHDR(&message, controlMessage); 220 } else { 221 ASSERT_NOT_REACHED(); 222 return; 66 223 } 67 68 if (m_socket->bytesAvailable() < m_currentMessageSize) 69 return;70 71 if (m_readBuffer.size() < m_currentMessageSize)72 m_readBuffer.grow(m_currentMessageSize); 73 74 size_t numberOfBytesRead = m_socket->read(reinterpret_cast<char*>(m_readBuffer.data()), m_currentMessageSize);75 ASSERT_UNUSED(numberOfBytesRead, numberOfBytesRead); 76 77 // The messageID is encoded at the end of the buffer.78 size_t realBufferSize = m_currentMessageSize - sizeof(uint32_t);79 uint32_t messageID = *reinterpret_cast<uint32_t*>(m_readBuffer.data() + realBufferSize);80 81 processIncomingMessage(MessageID::fromInt(messageID), adoptPtr(new ArgumentDecoder(m_readBuffer.data(), realBufferSize))); 82 83 m_currentMessageSize = 0; 84 }224 } 225 226 ASSERT(attachments.size() == messageInfo.isMessageBodyOOL() ? messageInfo.attachmentCount() - 1 : messageInfo.attachmentCount()); 227 228 unsigned char* messageBody = messageData; 229 230 if (messageInfo.isMessageBodyOOL()) 231 messageBody = reinterpret_cast<unsigned char*>(oolMessageBody->data()); 232 233 ArgumentDecoder* argumentDecoder; 234 if (attachments.isEmpty()) 235 argumentDecoder = new ArgumentDecoder(messageBody, messageInfo.bodySize()); 236 else 237 argumentDecoder = new ArgumentDecoder(messageBody, messageInfo.bodySize(), attachments); 238 239 processIncomingMessage(messageInfo.messageID(), adoptPtr(argumentDecoder)); 240 241 ASSERT(!controlMessage); 85 242 } 86 243 87 244 bool Connection::open() 88 245 { 89 ASSERT(!m_socket); 90 91 if (m_isServer) { 92 m_socket = WebKit::ProcessLauncher::takePendingConnection(); 93 m_isConnected = m_socket; 94 if (m_isConnected) { 95 m_connectionQueue.moveSocketToWorkThread(m_socket); 96 m_connectionQueue.connectSignal(m_socket, SIGNAL(readyRead()), WorkItem::create(this, &Connection::readyReadHandler)); 246 ASSERT(!m_socketNotifier); 247 int flags = fcntl(m_socketDescriptor, F_GETFL, 0); 248 while (fcntl(m_socketDescriptor, F_SETFL, flags | O_NONBLOCK) == -1) { 249 if (errno != EINTR) { 250 ASSERT_NOT_REACHED(); 251 return false; 97 252 } 98 } else { 99 m_socket = new QLocalSocket(); 100 m_socket->connectToServer(m_serverName); 101 m_connectionQueue.moveSocketToWorkThread(m_socket); 102 m_connectionQueue.connectSignal(m_socket, SIGNAL(readyRead()), WorkItem::create(this, &Connection::readyReadHandler)); 103 m_connectionQueue.connectSignal(m_socket, SIGNAL(disconnected()), WorkItem::create(this, &Connection::connectionDidClose)); 104 m_isConnected = m_socket->waitForConnected(); 105 } 106 return m_isConnected; 253 } 254 255 m_isConnected = true; 256 m_socketNotifier = m_connectionQueue.registerSocketEventHandler(m_socketDescriptor, QSocketNotifier::Read, WorkItem::create(this, &Connection::readyReadHandler)); 257 258 // Schedule a call to readyReadHandler. Data may have arrived before installation of the signal 259 // handler. 260 m_connectionQueue.scheduleWork(WorkItem::create(this, &Connection::readyReadHandler)); 261 262 return true; 107 263 } 108 264 109 265 bool Connection::platformCanSendOutgoingMessages() const 110 266 { 111 return m_socket ;267 return m_socketNotifier; 112 268 } 113 269 114 270 bool Connection::sendOutgoingMessage(MessageID messageID, PassOwnPtr<ArgumentEncoder> arguments) 115 271 { 116 ASSERT(m_socket); 117 118 // We put the message ID last. 119 arguments->encodeUInt32(messageID.toInt()); 120 121 size_t bufferSize = arguments->bufferSize(); 122 123 // Write message size first 124 // FIXME: Should just do a single write. 125 qint64 bytesWrittenForSize = m_socket->write(reinterpret_cast<char*>(&bufferSize), sizeof(bufferSize)); 126 if (bytesWrittenForSize != sizeof(bufferSize)) { 127 connectionDidClose(); 272 ASSERT(m_socketNotifier); 273 COMPILE_ASSERT(sizeof(MessageInfo) + attachmentMaxAmount * sizeof(size_t) <= messageMaxSize, AttachmentsFitToMessageInline); 274 275 Vector<Attachment> attachments = arguments->releaseAttachments(); 276 AttachmentResourceGuard<Vector<Attachment>, Vector<Attachment>::iterator> attachementDisposer(attachments); 277 278 if (attachments.size() > (attachmentMaxAmount - 1)) { 279 ASSERT_NOT_REACHED(); 128 280 return false; 129 281 } 130 282 131 qint64 bytesWrittenForBuffer = m_socket->write(reinterpret_cast<char*>(arguments->buffer()), arguments->bufferSize()); 132 if (bytesWrittenForBuffer != arguments->bufferSize()) { 133 connectionDidClose(); 134 return false; 135 } 136 137 m_socket->flush(); 138 283 MessageInfo messageInfo(messageID, arguments->bufferSize(), attachments.size()); 284 size_t messageSizeWithBodyInline = sizeof(messageInfo) + (attachments.size() * sizeof(size_t)) + arguments->bufferSize(); 285 if (messageSizeWithBodyInline > messageMaxSize && arguments->bufferSize()) { 286 RefPtr<WebKit::SharedMemory> oolMessageBody = WebKit::SharedMemory::create(arguments->bufferSize()); 287 if (!oolMessageBody) 288 return false; 289 290 WebKit::SharedMemory::Handle handle; 291 if (!oolMessageBody->createHandle(handle, WebKit::SharedMemory::ReadOnly)) 292 return false; 293 294 messageInfo.setMessageBodyOOL(); 295 296 memcpy(oolMessageBody->data(), arguments->buffer(), arguments->bufferSize()); 297 298 attachments.append(handle.releaseToAttachment()); 299 } 300 301 struct msghdr message; 302 memset(&message, 0, sizeof(message)); 303 304 struct iovec iov[3]; 305 memset(&iov, 0, sizeof(iov)); 306 307 message.msg_iov = iov; 308 int iovLength = 1; 309 310 iov[0].iov_base = reinterpret_cast<void*>(&messageInfo); 311 iov[0].iov_len = sizeof(messageInfo); 312 313 char attachmentFDBuffer[CMSG_SPACE(sizeof(int) * (attachments.size()))]; 314 size_t attachmentSizes[attachments.size()]; 315 316 if (!attachments.isEmpty()) { 317 message.msg_control = attachmentFDBuffer; 318 message.msg_controllen = sizeof(attachmentFDBuffer); 319 320 struct cmsghdr* cmsg = CMSG_FIRSTHDR(&message); 321 cmsg->cmsg_level = SOL_SOCKET; 322 cmsg->cmsg_type = SCM_RIGHTS; 323 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * attachments.size()); 324 325 int* fdptr = reinterpret_cast<int*>(CMSG_DATA(cmsg)); 326 for (int i = 0; i < attachments.size(); ++i) { 327 attachmentSizes[i] = attachments[i].size(); 328 fdptr[i] = attachments[i].fileDescriptor(); 329 } 330 331 message.msg_controllen = cmsg->cmsg_len; 332 333 iov[iovLength].iov_base = attachmentSizes; 334 iov[iovLength].iov_len = sizeof(attachmentSizes); 335 ++iovLength; 336 } 337 338 if (!messageInfo.isMessageBodyOOL() && arguments->bufferSize()) { 339 iov[iovLength].iov_base = reinterpret_cast<void*>(arguments->buffer()); 340 iov[iovLength].iov_len = arguments->bufferSize(); 341 ++iovLength; 342 } 343 344 message.msg_iovlen = iovLength; 345 346 int bytesSent = 0; 347 while ((bytesSent = sendmsg(m_socketDescriptor, &message, 0)) == -1) { 348 if (errno != EINTR) 349 return false; 350 } 139 351 return true; 140 352 } 141 353 354 void Connection::setShouldCloseConnectionOnProcessTermination(WebKit::PlatformProcessIdentifier process) 355 { 356 m_connectionQueue.scheduleWorkOnTermination(process, WorkItem::create(this, &Connection::connectionDidClose)); 357 } 358 142 359 } // namespace CoreIPC -
trunk/Source/WebKit2/Platform/SharedMemory.h
r76248 r76507 32 32 33 33 #if PLATFORM(QT) 34 #include <QtGlobal> 35 QT_BEGIN_NAMESPACE 36 class QSharedMemory; 37 QT_END_NAMESPACE 34 #include "Attachment.h" 38 35 #include <wtf/text/WTFString.h> 39 36 #endif … … 64 61 static bool decode(CoreIPC::ArgumentDecoder*, Handle&); 65 62 63 #if PLATFORM(QT) 64 CoreIPC::Attachment releaseToAttachment() const; 65 void adoptFromAttachment(int fileDescriptor, size_t); 66 #endif 66 67 private: 67 68 friend class SharedMemory; … … 71 72 mutable HANDLE m_handle; 72 73 #elif PLATFORM(QT) 73 mutable String m_key;74 mutable int m_fileDescriptor; 74 75 #endif 75 76 size_t m_size; … … 98 99 HANDLE m_handle; 99 100 #elif PLATFORM(QT) 100 QSharedMemory* m_impl;101 int m_fileDescriptor; 101 102 #endif 102 103 }; -
trunk/Source/WebKit2/Platform/WorkQueue.h
r73142 r76507 42 42 43 43 #if PLATFORM(QT) 44 class QLocalSocket; 44 #include <QSocketNotifier> 45 #include "PlatformProcessIdentifier.h" 45 46 class QObject; 46 47 class QThread; … … 80 81 void unregisterAndCloseHandle(HANDLE); 81 82 #elif PLATFORM(QT) 82 void connectSignal(QObject*, const char* signal, PassOwnPtr<WorkItem>); 83 void disconnectSignal(QObject*, const char* signal); 84 85 void moveSocketToWorkThread(QLocalSocket*); 83 QSocketNotifier* registerSocketEventHandler(int, QSocketNotifier::Type, PassOwnPtr<WorkItem>); 84 void scheduleWorkOnTermination(WebKit::PlatformProcessIdentifier, PassOwnPtr<WorkItem>); 86 85 #elif PLATFORM(GTK) 87 86 void registerEventSourceHandler(int, int, PassOwnPtr<WorkItem>); -
trunk/Source/WebKit2/Platform/qt/SharedMemoryQt.cpp
r75935 r76507 30 30 #include "ArgumentDecoder.h" 31 31 #include "ArgumentEncoder.h" 32 #include "CleanupHandler.h"33 32 #include "WebCoreArgumentCoders.h" 33 #include <QDir> 34 #include <errno.h> 35 #include <fcntl.h> 36 #include <stdlib.h> 37 #include <sys/mman.h> 38 #include <sys/stat.h> 39 #include <sys/types.h> 34 40 #include <unistd.h> 35 #include <QCoreApplication>36 #include <QLatin1String>37 #include <QSharedMemory>38 #include <QString>39 #include <QUuid>40 41 #include <wtf/Assertions.h> 41 42 #include <wtf/CurrentTime.h> … … 44 45 45 46 SharedMemory::Handle::Handle() 46 : m_ key()47 : m_fileDescriptor(-1) 47 48 , m_size(0) 48 49 { … … 51 52 SharedMemory::Handle::~Handle() 52 53 { 54 if (!isNull()) 55 while (close(m_fileDescriptor) == -1 && errno == EINTR) { } 53 56 } 54 57 55 58 bool SharedMemory::Handle::isNull() const 56 59 { 57 return m_ key.isNull();60 return m_fileDescriptor == -1; 58 61 } 59 62 60 63 void SharedMemory::Handle::encode(CoreIPC::ArgumentEncoder* encoder) const 61 64 { 62 encoder->encodeUInt64(m_size);63 encoder->encode(m_key); 64 m_key = String();65 ASSERT(!isNull()); 66 67 encoder->encode(releaseToAttachment()); 65 68 } 66 69 … … 68 71 { 69 72 ASSERT_ARG(handle, !handle.m_size); 70 ASSERT_ARG(handle, handle. m_key.isNull());71 72 uint64_t size;73 if (!decoder->decode UInt64(size))73 ASSERT_ARG(handle, handle.isNull()); 74 75 CoreIPC::Attachment attachment; 76 if (!decoder->decode(attachment)) 74 77 return false; 75 78 76 String key; 77 if (!decoder->decode(key)) 78 return false; 79 80 handle.m_size = size; 81 handle.m_key = key; 82 79 handle.adoptFromAttachment(attachment.releaseFileDescriptor(), attachment.size()); 83 80 return true; 84 81 } 85 82 86 static QString createUniqueKey() 87 { 88 return QLatin1String("QWKSharedMemoryKey") + QUuid::createUuid().toString(); 83 CoreIPC::Attachment SharedMemory::Handle::releaseToAttachment() const 84 { 85 ASSERT(!isNull()); 86 87 int temp = m_fileDescriptor; 88 m_fileDescriptor = -1; 89 return CoreIPC::Attachment(temp, m_size); 90 } 91 92 void SharedMemory::Handle::adoptFromAttachment(int fileDescriptor, size_t size) 93 { 94 ASSERT(!m_size); 95 ASSERT(isNull()); 96 97 m_fileDescriptor = fileDescriptor; 98 m_size = size; 89 99 } 90 100 91 101 PassRefPtr<SharedMemory> SharedMemory::create(size_t size) 92 102 { 93 RefPtr<SharedMemory> sharedMemory(adoptRef(new SharedMemory)); 94 QSharedMemory* impl = new QSharedMemory(createUniqueKey()); 95 bool created = impl->create(size); 96 ASSERT_UNUSED(created, created); 97 98 sharedMemory->m_impl = impl; 99 sharedMemory->m_size = size; 100 sharedMemory->m_data = impl->data(); 101 102 // Do not leave the shared memory segment behind. 103 CleanupHandler::instance()->markForCleanup(impl); 104 105 return sharedMemory.release(); 106 } 107 108 static inline QSharedMemory::AccessMode accessMode(SharedMemory::Protection protection) 103 QString tempName = QDir::temp().filePath("qwkshm.XXXXXX"); 104 QByteArray tempNameCSTR = tempName.toLocal8Bit(); 105 char* tempNameC = tempNameCSTR.data(); 106 107 int fileDescriptor; 108 while ((fileDescriptor = mkostemp(tempNameC, O_CREAT | O_CLOEXEC | O_RDWR)) == -1) { 109 if (errno != EINTR) 110 return 0; 111 } 112 113 while (ftruncate(fileDescriptor, size) == -1) { 114 if (errno != EINTR) { 115 while (close(fileDescriptor) == -1 && errno == EINTR) { } 116 unlink(tempNameC); 117 return 0; 118 } 119 } 120 121 void* data = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileDescriptor, 0); 122 if (data == MAP_FAILED) { 123 while (close(fileDescriptor) == -1 && errno == EINTR) { } 124 unlink(tempNameC); 125 return 0; 126 } 127 128 unlink(tempNameC); 129 130 RefPtr<SharedMemory> instance = adoptRef(new SharedMemory()); 131 instance->m_data = data; 132 instance->m_fileDescriptor = fileDescriptor; 133 instance->m_size = size; 134 return instance.release(); 135 } 136 137 static inline int accessModeMMap(SharedMemory::Protection protection) 109 138 { 110 139 switch (protection) { 111 140 case SharedMemory::ReadOnly: 112 return QSharedMemory::ReadOnly;141 return PROT_READ; 113 142 case SharedMemory::ReadWrite: 114 return QSharedMemory::ReadWrite;143 return PROT_READ | PROT_WRITE; 115 144 } 116 145 117 146 ASSERT_NOT_REACHED(); 118 return QSharedMemory::ReadWrite;147 return PROT_READ | PROT_WRITE; 119 148 } 120 149 121 150 PassRefPtr<SharedMemory> SharedMemory::create(const Handle& handle, Protection protection) 122 151 { 123 if (handle.isNull()) 152 ASSERT(!handle.isNull()); 153 154 void* data = mmap(0, handle.m_size, accessModeMMap(protection), MAP_SHARED, handle.m_fileDescriptor, 0); 155 if (data == MAP_FAILED) 124 156 return 0; 125 157 126 QSharedMemory* impl = new QSharedMemory(QString(handle.m_key)); 127 bool attached = impl->attach(accessMode(protection)); 128 if (!attached) { 129 delete impl; 130 return 0; 131 } 132 133 RefPtr<SharedMemory> sharedMemory(adoptRef(new SharedMemory)); 134 sharedMemory->m_impl = impl; 135 ASSERT(handle.m_size == impl->size()); 136 sharedMemory->m_size = handle.m_size; 137 sharedMemory->m_data = impl->data(); 138 139 // Do not leave the shared memory segment behind. 140 CleanupHandler::instance()->markForCleanup(impl); 141 142 return sharedMemory.release(); 158 RefPtr<SharedMemory> instance = adoptRef(new SharedMemory()); 159 instance->m_data = data; 160 instance->m_fileDescriptor = handle.m_fileDescriptor; 161 instance->m_size = handle.m_size; 162 handle.m_fileDescriptor = -1; 163 return instance; 143 164 } 144 165 145 166 SharedMemory::~SharedMemory() 146 167 { 147 if (CleanupHandler::instance()->hasStartedDeleting()) 148 return; 149 150 CleanupHandler::instance()->unmark(m_impl); 151 delete m_impl; 168 munmap(m_data, m_size); 169 while (close(m_fileDescriptor) == -1 && errno == EINTR) { } 170 } 171 172 static inline int accessModeFile(SharedMemory::Protection protection) 173 { 174 switch (protection) { 175 case SharedMemory::ReadOnly: 176 return O_RDONLY; 177 case SharedMemory::ReadWrite: 178 return O_RDWR; 179 } 180 181 ASSERT_NOT_REACHED(); 182 return O_RDWR; 152 183 } 153 184 154 185 bool SharedMemory::createHandle(Handle& handle, Protection protection) 155 186 { 156 ASSERT_ARG(handle, handle.m_key.isNull());157 187 ASSERT_ARG(handle, !handle.m_size); 158 159 QString key = m_impl->key(); 160 if (key.isNull()) 161 return false; 162 handle.m_key = String(key); 188 ASSERT_ARG(handle, handle.isNull()); 189 190 int duplicatedHandle; 191 while ((duplicatedHandle = dup(m_fileDescriptor)) == -1) { 192 if (errno != EINTR) { 193 ASSERT_NOT_REACHED(); 194 return false; 195 } 196 } 197 198 while ((fcntl(duplicatedHandle, F_SETFD, O_CLOEXEC | accessModeFile(protection)) == -1)) { 199 if (errno != EINTR) { 200 ASSERT_NOT_REACHED(); 201 while (close(duplicatedHandle) == -1 && errno == EINTR) { } 202 return false; 203 } 204 } 205 handle.m_fileDescriptor = duplicatedHandle; 163 206 handle.m_size = m_size; 164 165 207 return true; 166 208 } -
trunk/Source/WebKit2/Platform/qt/WorkQueueQt.cpp
r71456 r76507 30 30 #include <QObject> 31 31 #include <QThread> 32 #include <QProcess> 32 33 #include <wtf/Threading.h> 33 34 #include "NotImplemented.h" … … 76 77 }; 77 78 78 void WorkQueue::connectSignal(QObject* o, const char* signal, PassOwnPtr<WorkItem> workItem) 79 { 80 WorkQueue::WorkItemQt* itemQt = new WorkQueue::WorkItemQt(this, o, signal, workItem.leakPtr()); 81 itemQt->moveToThread(m_workThread); 82 m_signalListeners.add(o, itemQt); 83 } 84 85 void WorkQueue::disconnectSignal(QObject* o, const char* name) 86 { 87 HashMap<QObject*, WorkItemQt*>::iterator it = m_signalListeners.find(o); 88 for (; it != m_signalListeners.end(); ++it) { 89 if (strcmp(it->second->m_signal, name)) 90 continue; 91 delete it->second; 92 m_signalListeners.remove(it); 93 return; 94 } 95 } 96 97 void WorkQueue::moveSocketToWorkThread(QLocalSocket* socket) 79 QSocketNotifier* WorkQueue::registerSocketEventHandler(int socketDescriptor, QSocketNotifier::Type type, PassOwnPtr<WorkItem> workItem) 98 80 { 99 81 ASSERT(m_workThread); 100 ASSERT(socket);101 82 102 socket->setParent(0); 103 socket->moveToThread(m_workThread); 83 QSocketNotifier* notifier = new QSocketNotifier(socketDescriptor, type, 0); 84 notifier->setEnabled(false); 85 notifier->moveToThread(m_workThread); 86 WorkQueue::WorkItemQt* itemQt = new WorkQueue::WorkItemQt(this, notifier, SIGNAL(activated(int)), workItem.leakPtr()); 87 itemQt->moveToThread(m_workThread); 88 notifier->setEnabled(true); 89 return notifier; 104 90 } 105 91 … … 130 116 } 131 117 118 void WorkQueue::scheduleWorkOnTermination(WebKit::PlatformProcessIdentifier process, PassOwnPtr<WorkItem> workItem) 119 { 120 WorkQueue::WorkItemQt* itemQt = new WorkQueue::WorkItemQt(this, process, SIGNAL(finished(int, QProcess::ExitStatus)), workItem.leakPtr()); 121 itemQt->moveToThread(m_workThread); 122 } 123 132 124 #include "WorkQueueQt.moc" -
trunk/Source/WebKit2/Shared/qt/UpdateChunk.cpp
r72185 r76507 30 30 #include "ArgumentDecoder.h" 31 31 #include "ArgumentEncoder.h" 32 #include "MappedMemoryPool.h"33 32 #include "WebCoreArgumentCoders.h" 34 33 #include <QIODevice> … … 44 43 45 44 UpdateChunk::UpdateChunk() 46 : m_mappedMemory(0)47 45 { 48 46 } … … 50 48 UpdateChunk::UpdateChunk(const IntRect& rect) 51 49 : m_rect(rect) 52 , m_ mappedMemory(MappedMemoryPool::instance()->mapMemory(size()))50 , m_sharedMemory(SharedMemory::create(size())) 53 51 { 54 52 } … … 56 54 UpdateChunk::~UpdateChunk() 57 55 { 58 if (m_mappedMemory)59 m_mappedMemory->markFree();60 56 } 61 57 … … 63 59 { 64 60 encoder->encode(m_rect); 65 encoder->encode(String(m_mappedMemory->mappedFileName())); 61 if (!m_sharedMemory) { 62 encoder->encode(false); 63 return; 64 } 66 65 67 m_mappedMemory = 0; 66 SharedMemory::Handle handle; 67 if (m_sharedMemory->createHandle(handle, SharedMemory::ReadOnly)) { 68 encoder->encode(true); 69 encoder->encode(handle); 70 } else 71 encoder->encode(false); 72 73 m_sharedMemory = 0; 68 74 } 69 75 … … 75 81 if (!decoder->decode(rect)) 76 82 return false; 83 77 84 chunk.m_rect = rect; 78 85 79 if (chunk.isEmpty()) 80 return true; // Successfully decoded empty chunk. 81 82 String fileName; 83 if (!decoder->decode(fileName)) 86 bool hasSharedMemory; 87 if (!decoder->decode(hasSharedMemory)) 84 88 return false; 85 89 86 chunk.m_mappedMemory = MappedMemoryPool::instance()->mapFile(fileName, chunk.size()); 90 if (!hasSharedMemory) { 91 chunk.m_sharedMemory = 0; 92 return true; 93 } 94 95 SharedMemory::Handle handle; 96 if (!decoder->decode(handle)) 97 return false; 98 99 chunk.m_sharedMemory = SharedMemory::create(handle, SharedMemory::ReadOnly); 87 100 return true; 88 101 } … … 102 115 QImage UpdateChunk::createImage() const 103 116 { 104 ASSERT(m_mappedMemory); 117 ASSERT(m_sharedMemory); 118 if (!m_sharedMemory) 119 return QImage(); 120 105 121 QImage::Format format; 106 122 int bpp; … … 113 129 } 114 130 115 return QImage( m_mappedMemory->data(), m_rect.width(), m_rect.height(), (m_rect.width() * bpp + 3) & ~0x3, format);131 return QImage(reinterpret_cast<unsigned char*>(m_sharedMemory->data()), m_rect.width(), m_rect.height(), (m_rect.width() * bpp + 3) & ~0x3, format); 116 132 } 117 133 -
trunk/Source/WebKit2/Shared/qt/UpdateChunk.h
r72185 r76507 30 30 #include <QImage> 31 31 #include <WebCore/IntRect.h> 32 #include "SharedMemory.h" 32 33 33 34 namespace CoreIPC { … … 37 38 38 39 namespace WebKit { 39 40 class MappedMemory;41 40 42 41 class UpdateChunk { … … 59 58 WebCore::IntRect m_rect; 60 59 61 mutable MappedMemory* m_mappedMemory;60 mutable RefPtr<SharedMemory> m_sharedMemory; 62 61 }; 63 62 -
trunk/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h
r68391 r76507 73 73 static bool getProcessTypeFromString(const char*, ProcessType&); 74 74 75 #if PLATFORM(QT)76 friend class ProcessLauncherHelper;77 static QLocalSocket* takePendingConnection();78 #endif79 80 75 private: 81 76 ProcessLauncher(Client*, const LaunchOptions& launchOptions); -
trunk/Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp
r74967 r76507 28 28 29 29 #include "Connection.h" 30 #include "CleanupHandler.h"31 30 #include "NotImplemented.h" 32 31 #include "RunLoop.h" 33 32 #include "WebProcess.h" 34 #include <runtime/InitializeThreading.h>35 #include <string>36 #include <wtf/HashSet.h>37 #include <wtf/PassRefPtr.h>38 #include <wtf/Threading.h>39 #include <wtf/text/WTFString.h>40 41 33 #include <QApplication> 42 34 #include <QDebug> … … 46 38 #include <QProcess> 47 39 #include <QString> 48 49 40 #include <QtCore/qglobal.h> 50 41 #include <errno.h> 42 #include <fcntl.h> 43 #include <runtime/InitializeThreading.h> 44 #include <string> 51 45 #include <sys/resource.h> 46 #include <sys/socket.h> 52 47 #include <unistd.h> 48 #include <wtf/HashSet.h> 49 #include <wtf/PassRefPtr.h> 50 #include <wtf/Threading.h> 51 #include <wtf/text/WTFString.h> 52 #if defined Q_OS_UNIX 53 #include <sys/prctl.h> 54 #include <signal.h> 55 #endif 53 56 54 57 using namespace WebCore; 55 58 56 59 namespace WebKit { 57 58 class ProcessLauncherHelper : public QObject {59 Q_OBJECT60 public:61 ~ProcessLauncherHelper();62 void launch(WebKit::ProcessLauncher*);63 QLocalSocket* takePendingConnection();64 static ProcessLauncherHelper* instance();65 66 const QString serverName() const { return m_server.serverName(); }67 68 private:69 ProcessLauncherHelper();70 QLocalServer m_server;71 QList<WorkItem*> m_items;72 73 Q_SLOT void newConnection();74 };75 76 Q_GLOBAL_STATIC(WTF::HashSet<QProcess*>, processes);77 78 static void cleanupAtExit()79 {80 // Terminate our web process(es).81 WTF::HashSet<QProcess*>::const_iterator end = processes()->end();82 for (WTF::HashSet<QProcess*>::const_iterator it = processes()->begin(); it != end; ++it) {83 QProcess* process = *it;84 process->disconnect(process);85 process->terminate();86 if (!process->waitForFinished(200))87 process->kill();88 }89 90 // Do not leave the socket file behind.91 QLocalServer::removeServer(ProcessLauncherHelper::instance()->serverName());92 }93 60 94 61 class QtWebProcess : public QProcess … … 99 66 : QProcess(parent) 100 67 { 101 static bool isRegistered = false;102 if (!isRegistered) {103 qRegisterMetaType<QProcess::ProcessState>("QProcess::ProcessState");104 isRegistered = true;105 }106 107 connect(this, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(processStateChanged(QProcess::ProcessState)));108 68 } 109 69 110 pr ivate slots:111 v oid processStateChanged(QProcess::ProcessState state);70 protected: 71 virtual void setupChildProcess(); 112 72 }; 113 73 114 void QtWebProcess:: processStateChanged(QProcess::ProcessState state)74 void QtWebProcess::setupChildProcess() 115 75 { 116 QProcess* process = qobject_cast<QProcess*>(sender()); 117 if (!process) 118 return; 119 120 if (state == QProcess::Running) 121 processes()->add(process); 122 else if (state == QProcess::NotRunning) 123 processes()->remove(process); 76 #if defined Q_OS_UNIX 77 prctl(PR_SET_PDEATHSIG, SIGKILL); 78 #endif 124 79 } 125 80 126 void ProcessLauncher Helper::launch(WebKit::ProcessLauncher* launcher)81 void ProcessLauncher::launchProcess() 127 82 { 128 83 QString applicationPath = "%1 %2"; … … 134 89 } 135 90 136 QString program(applicationPath.arg(m_server.serverName())); 91 int sockets[2]; 92 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) == -1) { 93 qDebug() << "Creation of socket failed with errno:" << errno; 94 ASSERT_NOT_REACHED(); 95 return; 96 } 97 98 // Don't expose the ui socket to the web process 99 while (fcntl(sockets[1], F_SETFD, FD_CLOEXEC == -1)) { 100 if (errno != EINTR) { 101 ASSERT_NOT_REACHED(); 102 while (close(sockets[0]) == -1 && errno == EINTR) { } 103 while (close(sockets[1]) == -1 && errno == EINTR) { } 104 return; 105 } 106 } 107 108 QString program(applicationPath.arg(sockets[0])); 137 109 138 110 QProcess* webProcess = new QtWebProcess(); 139 111 webProcess->setProcessChannelMode(QProcess::ForwardedChannels); 140 112 webProcess->start(program); 113 114 // Don't expose the web socket to possible future web processes 115 while (fcntl(sockets[0], F_SETFD, FD_CLOEXEC) == -1) { 116 if (errno != EINTR) { 117 ASSERT_NOT_REACHED(); 118 delete webProcess; 119 return; 120 } 121 } 141 122 142 123 if (!webProcess->waitForStarted()) { … … 149 130 setpriority(PRIO_PROCESS, webProcess->pid(), 10); 150 131 151 m_items.append(WorkItem::create(launcher, &WebKit::ProcessLauncher::didFinishLaunchingProcess, webProcess, m_server.serverName()).leakPtr()); 152 } 153 154 QLocalSocket* ProcessLauncherHelper::takePendingConnection() 155 { 156 return m_server.nextPendingConnection(); 157 } 158 159 ProcessLauncherHelper::~ProcessLauncherHelper() 160 { 161 m_server.close(); 162 } 163 164 ProcessLauncherHelper::ProcessLauncherHelper() 165 { 166 srandom(time(0)); 167 if (!m_server.listen("QtWebKit" + QString::number(random()))) { 168 qDebug() << "Failed to create server socket."; 169 ASSERT_NOT_REACHED(); 170 } 171 connect(&m_server, SIGNAL(newConnection()), this, SLOT(newConnection())); 172 } 173 174 ProcessLauncherHelper* ProcessLauncherHelper::instance() 175 { 176 static ProcessLauncherHelper* result = 0; 177 if (!result) { 178 result = new ProcessLauncherHelper(); 179 180 // The purpose of the following line is to ensure that our static is initialized before the exit handler is installed. 181 processes()->clear(); 182 183 atexit(cleanupAtExit); 184 } 185 return result; 186 } 187 188 void ProcessLauncherHelper::newConnection() 189 { 190 ASSERT(!m_items.isEmpty()); 191 192 m_items[0]->execute(); 193 delete m_items[0]; 194 m_items.pop_front(); 195 } 196 197 void ProcessLauncher::launchProcess() 198 { 199 ProcessLauncherHelper::instance()->launch(this); 132 RunLoop::main()->scheduleWork(WorkItem::create(this, &WebKit::ProcessLauncher::didFinishLaunchingProcess, webProcess, sockets[1])); 200 133 } 201 134 … … 209 142 } 210 143 211 QLocalSocket* ProcessLauncher::takePendingConnection()212 {213 return ProcessLauncherHelper::instance()->takePendingConnection();214 }215 216 144 void ProcessLauncher::platformInvalidate() 217 145 { 218 notImplemented(); 146 219 147 } 220 148 -
trunk/Source/WebKit2/UIProcess/Launcher/qt/ThreadLauncherQt.cpp
r67433 r76507 55 55 // FIXME: We do not support threaded mode for now. 56 56 57 WebProcess::shared().initialize( "foo", RunLoop::current());57 WebProcess::shared().initialize(-1, RunLoop::current()); 58 58 RunLoop::run(); 59 59 … … 71 71 } 72 72 73 QString serverIdentifier = QString::number(connectionIdentifier); 74 return serverIdentifier; 73 return connectionIdentifier; 75 74 } 76 75 -
trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp
r75452 r76507 345 345 #if PLATFORM(MAC) 346 346 m_connection->setShouldCloseConnectionOnMachExceptions(); 347 #elif PLATFORM(QT) 348 m_connection->setShouldCloseConnectionOnProcessTermination(processIdentifier()); 347 349 #endif 348 350 349 351 m_connection->open(); 350 352 -
trunk/Source/WebKit2/UIProcess/qt/WebContextQt.cpp
r73221 r76507 29 29 #include "ApplicationCacheStorage.h" 30 30 #include "WebProcessCreationParameters.h" 31 #include <QProcess> 31 32 32 33 namespace WebKit { … … 43 44 void WebContext::platformInitializeWebProcess(WebProcessCreationParameters&) 44 45 { 46 qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus"); 45 47 } 46 48 -
trunk/Source/WebKit2/WebKit2.pro
r76496 r76507 233 233 Platform/WorkItem.h \ 234 234 Platform/WorkQueue.h \ 235 Platform/qt/MappedMemoryPool.h \236 235 Shared/API/c/WKBase.h \ 237 236 Shared/API/c/WKCertificateInfo.h \ … … 294 293 Shared/WebUserContentURLPattern.h \ 295 294 Shared/Plugins/Netscape/NetscapePluginModule.h \ 296 Shared/qt/CleanupHandler.h \297 295 Shared/qt/PlatformCertificateInfo.h \ 298 296 Shared/qt/UpdateChunk.h \ … … 460 458 Platform/CoreIPC/Connection.cpp \ 461 459 Platform/CoreIPC/DataReference.cpp \ 460 Platform/CoreIPC/qt/AttachmentQt.cpp \ 462 461 Platform/CoreIPC/qt/ConnectionQt.cpp \ 463 462 Platform/Logging.cpp \ … … 465 464 Platform/RunLoop.cpp \ 466 465 Platform/WorkQueue.cpp \ 467 Platform/qt/MappedMemoryPool.cpp \468 466 Platform/qt/ModuleQt.cpp \ 469 467 Platform/qt/RunLoopQt.cpp \ … … 518 516 Shared/WebWheelEvent.cpp \ 519 517 Shared/qt/ShareableBitmapQt.cpp \ 520 Shared/qt/CleanupHandler.cpp \521 518 Shared/qt/NativeWebKeyboardEventQt.cpp \ 522 519 Shared/qt/UpdateChunk.cpp \ -
trunk/Source/WebKit2/WebProcess/qt/WebProcessMainQt.cpp
r75046 r76507 161 161 162 162 // Create the connection. 163 QString identifier(app->arguments().size() > 1 ? app->arguments().at(1) : ""); 163 if (app->arguments().size() <= 1) { 164 qDebug() << "Error: wrong number of arguments."; 165 return 1; 166 } 167 168 bool wasNumber = false; 169 int identifier = app->arguments().at(1).toInt(&wasNumber, 10); 170 if (!wasNumber) { 171 qDebug() << "Error: connection identifier wrong."; 172 return 1; 173 } 174 164 175 WebKit::WebProcess::shared().initialize(identifier, RunLoop::main()); 165 176
Note: See TracChangeset
for help on using the changeset viewer.