bool Connection::sendOutgoingMessage(MessageID messageID, PassOwnPtr<ArgumentEncoder> arguments) { ASSERT(m_socket); // We put the message ID last. arguments->encodeUInt32(messageID.toInt()); size_t bufferSize = arguments->bufferSize(); // Write message size first // FIXME: Should just do a single write. qint64 bytesWrittenForSize = m_socket->write(reinterpret_cast<char*>(&bufferSize), sizeof(bufferSize)); if (bytesWrittenForSize != sizeof(bufferSize)) { connectionDidClose(); return false; } qint64 bytesWrittenForBuffer = m_socket->write(reinterpret_cast<char*>(arguments->buffer()), arguments->bufferSize()); if (bytesWrittenForBuffer != arguments->bufferSize()) { connectionDidClose(); return false; } m_socket->flush(); return true; }
bool Connection::sendOutgoingMessage(MessageID messageID, PassOwnPtr<ArgumentEncoder> arguments) { ASSERT(m_socket); // We put the message ID last. arguments->encodeUInt32(messageID.toInt()); size_t bufferSize = arguments->bufferSize(); // Write message size first // FIXME: Should just do a single write. m_socket->write(reinterpret_cast<char*>(&bufferSize), sizeof(bufferSize)); qint64 bytesWritten = m_socket->write(reinterpret_cast<char*>(arguments->buffer()), arguments->bufferSize()); ASSERT_UNUSED(bytesWritten, bytesWritten == arguments->bufferSize()); return true; }
bool Connection::sendOutgoingMessage(MessageID messageID, PassOwnPtr<ArgumentEncoder> arguments) { if (m_socket < 0) return false; // We put the message ID last. arguments->encodeUInt32(messageID.toInt()); size_t bufferSize = arguments->bufferSize(); // Send the message size first. if (!writeBytesToSocket(m_socket, reinterpret_cast<uint8_t*>(&bufferSize), sizeof(size_t))) return false; if (!writeBytesToSocket(m_socket, arguments->buffer(), arguments->bufferSize())) return false; return true; }
bool Connection::sendOutgoingMessage(MessageID messageID, PassOwnPtr<MessageEncoder> encoder) { ASSERT(!m_pendingWriteEncoder); // Just bail if the handle has been closed. if (m_connectionPipe == INVALID_HANDLE_VALUE) return false; // We put the message ID last. encoder->encode(static_cast<uint32_t>(messageID.toInt())); // Write the outgoing message. if (::WriteFile(m_connectionPipe, encoder->buffer(), encoder->bufferSize(), 0, &m_writeState)) { // We successfully sent this message. return true; } DWORD error = ::GetLastError(); if (error == ERROR_NO_DATA) { // The pipe is being closed. connectionDidClose(); return false; } if (error != ERROR_IO_PENDING) { ASSERT_NOT_REACHED(); return false; } // The message will be sent soon. Hold onto the encoder so that it won't be destroyed // before the write completes. m_pendingWriteEncoder = encoder; // We can only send one asynchronous message at a time (see comment in platformCanSendOutgoingMessages). return false; }
bool Connection::sendOutgoingMessage(MessageID messageID, PassOwnPtr<ArgumentEncoder> arguments) { Vector<Attachment> attachments = arguments->releaseAttachments(); size_t numberOfPortDescriptors = 0; size_t numberOfOOLMemoryDescriptors = 0; for (size_t i = 0; i < attachments.size(); ++i) { Attachment::Type type = attachments[i].type(); if (type == Attachment::MachPortType) numberOfPortDescriptors++; else if (type == Attachment::MachOOLMemoryType) numberOfOOLMemoryDescriptors++; } size_t messageSize = machMessageSize(arguments->bufferSize(), numberOfPortDescriptors, numberOfOOLMemoryDescriptors); char buffer[inlineMessageMaxSize]; bool messageBodyIsOOL = false; if (messageSize > sizeof(buffer)) { messageBodyIsOOL = true; attachments.append(Attachment(arguments->buffer(), arguments->bufferSize(), MACH_MSG_VIRTUAL_COPY, false)); numberOfOOLMemoryDescriptors++; messageSize = machMessageSize(0, numberOfPortDescriptors, numberOfOOLMemoryDescriptors); } bool isComplex = (numberOfPortDescriptors + numberOfOOLMemoryDescriptors > 0); mach_msg_header_t* header = reinterpret_cast<mach_msg_header_t*>(&buffer); header->msgh_bits = isComplex ? MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND | MACH_MSGH_BITS_COMPLEX, 0) : MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0); header->msgh_size = messageSize; header->msgh_remote_port = m_sendPort; header->msgh_local_port = MACH_PORT_NULL; header->msgh_id = messageID.toInt(); if (messageBodyIsOOL) header->msgh_id |= MessageBodyIsOOL; uint8_t* messageData; if (isComplex) { mach_msg_body_t* body = reinterpret_cast<mach_msg_body_t*>(header + 1); body->msgh_descriptor_count = numberOfPortDescriptors + numberOfOOLMemoryDescriptors; uint8_t* descriptorData = reinterpret_cast<uint8_t*>(body + 1); for (size_t i = 0; i < attachments.size(); ++i) { Attachment attachment = attachments[i]; mach_msg_descriptor_t* descriptor = reinterpret_cast<mach_msg_descriptor_t*>(descriptorData); switch (attachment.type()) { case Attachment::MachPortType: descriptor->port.name = attachment.port(); descriptor->port.disposition = attachment.disposition(); descriptor->port.type = MACH_MSG_PORT_DESCRIPTOR; descriptorData += sizeof(mach_msg_port_descriptor_t); break; case Attachment::MachOOLMemoryType: descriptor->out_of_line.address = attachment.address(); descriptor->out_of_line.size = attachment.size(); descriptor->out_of_line.copy = attachment.copyOptions(); descriptor->out_of_line.deallocate = attachment.deallocate(); descriptor->out_of_line.type = MACH_MSG_OOL_DESCRIPTOR; descriptorData += sizeof(mach_msg_ool_descriptor_t); break; default: ASSERT_NOT_REACHED(); } } messageData = descriptorData; } else messageData = (uint8_t*)(header + 1); // Copy the data if it is not being sent out-of-line. if (!messageBodyIsOOL) memcpy(messageData, arguments->buffer(), arguments->bufferSize()); ASSERT(m_sendPort); // Send the message. kern_return_t kr = mach_msg(header, MACH_SEND_MSG, messageSize, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (kr != KERN_SUCCESS) { // FIXME: What should we do here? } return true; }