Exemple #1
0
bool Connection::open()
{
    if (m_isServer) {
        ASSERT(m_receivePort);
        ASSERT(!m_sendPort);
        
    } else {
        ASSERT(!m_receivePort);
        ASSERT(m_sendPort);

        // Create the receive port.
        mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &m_receivePort);

        m_isConnected = true;
        
        // Send the initialize message, which contains a send right for the server to use.
        send(CoreIPCMessage::InitializeConnection, 0, MachPort(m_receivePort, MACH_MSG_TYPE_MAKE_SEND));

        // Set the dead name handler for our send port.
        initializeDeadNameSource();
    }
    
    // Register the data available handler.
    m_connectionQueue.registerMachPortEventHandler(m_receivePort, WorkQueue::MachPortDataAvailable, 
                                                   WorkItem::create(this, &Connection::receiveSourceEventHandler));

    return true;
}
Exemple #2
0
void Connection::receiveSourceEventHandler()
{
    ReceiveBuffer buffer;

    mach_msg_header_t* header = readFromMachPort(m_receivePort, buffer);
    if (!header)
        return;

    MessageID messageID = MessageID::fromInt(header->msgh_id);
    OwnPtr<ArgumentDecoder> arguments = createArgumentDecoder(header);
    ASSERT(arguments);

    if (messageID == MessageID(CoreIPCMessage::InitializeConnection)) {
        ASSERT(m_isServer);
        ASSERT(!m_isConnected);
        ASSERT(!m_sendPort);

        MachPort port;
        if (!arguments->decode(port)) {
            // FIXME: Disconnect.
            return;
        }

        m_sendPort = port.port();
        
        // Set the dead name source if needed.
        if (m_sendPort)
            initializeDeadNameSource();
        
        m_isConnected = true;

        // Send any pending outgoing messages.
        sendOutgoingMessages();
        
        return;
    }

    if (messageID == MessageID(CoreIPCMessage::SetExceptionPort)) {
        MachPort exceptionPort;
        if (!arguments->decode(exceptionPort))
            return;

        setMachExceptionPort(exceptionPort.port());
        return;
    }

    processIncomingMessage(messageID, arguments.release());
}    
Exemple #3
0
void Connection::receiveSourceEventHandler()
{
    char buffer[inlineMessageMaxSize];
    
    mach_msg_header_t* header = reinterpret_cast<mach_msg_header_t*>(&buffer);
    
    kern_return_t kr = mach_msg(header, MACH_RCV_MSG | MACH_RCV_LARGE | MACH_RCV_TIMEOUT, 0, sizeof(buffer), m_receivePort, 0, MACH_PORT_NULL);
    if (kr == MACH_RCV_TIMED_OUT)
        return;

    if (kr != MACH_MSG_SUCCESS) {

        ASSERT_NOT_REACHED();
        // FIXME: Handle MACH_RCV_MSG_TOO_LARGE.
        return;
    }
    
    MessageID messageID = MessageID::fromInt(header->msgh_id);
    std::auto_ptr<ArgumentDecoder> arguments = createArgumentDecoder(header);
    ASSERT(arguments.get());

    if (messageID == MessageID(CoreIPCMessage::InitializeConnection)) {
        ASSERT(m_isServer);
        ASSERT(!m_isConnected);
        ASSERT(!m_sendPort);

        MachPort port;
        if (!arguments->decode(port)) {
            // FIXME: Disconnect.
            return;
        }

        m_sendPort = port.port();
        
        // Set the dead name source if needed.
        if (m_sendPort)
            initializeDeadNameSource();
        
        m_isConnected = true;

        // Send any pending outgoing messages.
        sendOutgoingMessages();
        
        return;
    }
    
    processIncomingMessage(messageID, arguments);
}    
Exemple #4
0
bool Connection::open()
{
    if (m_isServer) {
        ASSERT(m_receivePort);
        ASSERT(!m_sendPort);
        
    } else {
        ASSERT(!m_receivePort);
        ASSERT(m_sendPort);

        // Create the receive port.
        mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &m_receivePort);

        m_isConnected = true;
        
        // Send the initialize message, which contains a send right for the server to use.
        OwnPtr<MessageEncoder> encoder = MessageEncoder::create("IPC", "InitializeConnection", 0);
        encoder->encode(MachPort(m_receivePort, MACH_MSG_TYPE_MAKE_SEND));

        sendMessage(MessageID(), encoder.release());

        // Set the dead name handler for our send port.
        initializeDeadNameSource();
    }

    // Change the message queue length for the receive port.
    setMachPortQueueLength(m_receivePort, MACH_PORT_QLIMIT_LARGE);

    // Register the data available handler.
    m_connectionQueue.registerMachPortEventHandler(m_receivePort, WorkQueue::MachPortDataAvailable, bind(&Connection::receiveSourceEventHandler, this));

    // If we have an exception port, register the data available handler and send over the port to the other end.
    if (m_exceptionPort) {
        m_connectionQueue.registerMachPortEventHandler(m_exceptionPort, WorkQueue::MachPortDataAvailable, bind(&Connection::exceptionSourceEventHandler, this));

        OwnPtr<MessageEncoder> encoder = MessageEncoder::create("IPC", "SetExceptionPort", 0);
        encoder->encode(MachPort(m_exceptionPort, MACH_MSG_TYPE_MAKE_SEND));

        sendMessage(MessageID(), encoder.release());
    }

    return true;
}