Changeset 141037 in webkit


Ignore:
Timestamp:
Jan 28, 2013 7:47:01 PM (11 years ago)
Author:
andersca@apple.com
Message:

Move Mach port handling from WorkQueue to Connection
https://bugs.webkit.org/show_bug.cgi?id=108140

Reviewed by Sam Weinig.

Instead of having WorkQueue know about Mach port sources, just fold that
functionality directly into Connection. This lets us get rid of the generic source
handling from WorkQueue.

  • Platform/CoreIPC/Connection.h:

(Connection):

  • Platform/CoreIPC/mac/ConnectionMac.cpp:

(CoreIPC::Connection::platformInvalidate):
(CoreIPC::createDataAvailableSource):
(CoreIPC):
(CoreIPC::Connection::open):
(CoreIPC::Connection::initializeDeadNameSource):

  • Platform/WorkQueue.h:

(WorkQueue::dispatchQueue):
(WorkQueue):

  • Platform/mac/WorkQueueMac.cpp:

(WorkQueue::platformInvalidate):

Location:
trunk/Source/WebKit2
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r141032 r141037  
     12013-01-28  Anders Carlsson  <andersca@apple.com>
     2
     3        Move Mach port handling from WorkQueue to Connection
     4        https://bugs.webkit.org/show_bug.cgi?id=108140
     5
     6        Reviewed by Sam Weinig.
     7
     8        Instead of having WorkQueue know about Mach port sources, just fold that
     9        functionality directly into Connection. This lets us get rid of the generic source
     10        handling from WorkQueue.
     11
     12        * Platform/CoreIPC/Connection.h:
     13        (Connection):
     14        * Platform/CoreIPC/mac/ConnectionMac.cpp:
     15        (CoreIPC::Connection::platformInvalidate):
     16        (CoreIPC::createDataAvailableSource):
     17        (CoreIPC):
     18        (CoreIPC::Connection::open):
     19        (CoreIPC::Connection::initializeDeadNameSource):
     20        * Platform/WorkQueue.h:
     21        (WorkQueue::dispatchQueue):
     22        (WorkQueue):
     23        * Platform/mac/WorkQueueMac.cpp:
     24        (WorkQueue::platformInvalidate):
     25
    1262013-01-28  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
    227
  • trunk/Source/WebKit2/Platform/CoreIPC/Connection.h

    r139514 r141037  
    352352
    353353    mach_port_t m_sendPort;
     354    dispatch_source_t m_deadNameSource;
     355
    354356    mach_port_t m_receivePort;
     357    dispatch_source_t m_receivePortDataAvailableSource;
    355358
    356359    // If setShouldCloseConnectionOnMachExceptions has been called, this has
    357360    // the exception port that exceptions from the other end will be sent on.
    358361    mach_port_t m_exceptionPort;
     362    dispatch_source_t m_exceptionPortDataAvailableSource;
    359363
    360364#if HAVE(XPC)
  • trunk/Source/WebKit2/Platform/CoreIPC/mac/ConnectionMac.cpp

    r139919 r141037  
    5959
    6060    // Unregister our ports.
    61     m_connectionQueue.unregisterMachPortEventHandler(m_sendPort);
     61    dispatch_source_cancel(m_deadNameSource);
     62    dispatch_release(m_deadNameSource);
     63    m_deadNameSource = nullptr;
    6264    m_sendPort = MACH_PORT_NULL;
    6365
    64     m_connectionQueue.unregisterMachPortEventHandler(m_receivePort);
     66    dispatch_source_cancel(m_receivePortDataAvailableSource);
     67    dispatch_release(m_receivePortDataAvailableSource);
     68    m_receivePortDataAvailableSource = nullptr;
    6569    m_receivePort = MACH_PORT_NULL;
    6670
    6771    if (m_exceptionPort) {
    68         m_connectionQueue.unregisterMachPortEventHandler(m_exceptionPort);
     72        dispatch_source_cancel(m_exceptionPortDataAvailableSource);
     73        dispatch_release(m_exceptionPortDataAvailableSource);
     74        m_exceptionPortDataAvailableSource = nullptr;
    6975        m_exceptionPort = MACH_PORT_NULL;
    7076    }
     
    7379    if (m_xpcConnection) {
    7480        xpc_release(m_xpcConnection);
    75         m_xpcConnection = 0;
     81        m_xpcConnection = nullptr;
    7682    }
    7783#endif
     
    99105}
    100106
     107static dispatch_source_t createDataAvailableSource(mach_port_t receivePort, const WorkQueue& workQueue, const Function<void()>& function)
     108{
     109    dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, receivePort, 0, workQueue.dispatchQueue());
     110    dispatch_source_set_event_handler(source, function);
     111    dispatch_source_set_cancel_handler(source, ^{
     112        mach_port_mod_refs(mach_task_self(), receivePort, MACH_PORT_RIGHT_RECEIVE, -1);
     113    });
     114
     115    return source;
     116}
     117
    101118bool Connection::open()
    102119{
     
    128145
    129146    // Register the data available handler.
    130     m_connectionQueue.registerMachPortEventHandler(m_receivePort, WorkQueue::MachPortDataAvailable, bind(&Connection::receiveSourceEventHandler, this));
     147    m_receivePortDataAvailableSource = createDataAvailableSource(m_receivePort, m_connectionQueue, bind(&Connection::receiveSourceEventHandler, this));
     148    dispatch_resume(m_receivePortDataAvailableSource);
    131149
    132150    // If we have an exception port, register the data available handler and send over the port to the other end.
    133151    if (m_exceptionPort) {
    134         m_connectionQueue.registerMachPortEventHandler(m_exceptionPort, WorkQueue::MachPortDataAvailable, bind(&Connection::exceptionSourceEventHandler, this));
     152        m_exceptionPortDataAvailableSource = createDataAvailableSource(m_exceptionPort, m_connectionQueue, bind(&Connection::exceptionSourceEventHandler, this));
     153        dispatch_resume(m_exceptionPortDataAvailableSource);
    135154
    136155        OwnPtr<MessageEncoder> encoder = MessageEncoder::create("IPC", "SetExceptionPort", 0);
     
    252271void Connection::initializeDeadNameSource()
    253272{
    254     m_connectionQueue.registerMachPortEventHandler(m_sendPort, WorkQueue::MachPortDeadNameNotification, bind(&Connection::connectionDidClose, this));
     273    m_deadNameSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_SEND, m_sendPort, 0, m_connectionQueue.dispatchQueue());
     274    dispatch_source_set_event_handler(m_deadNameSource, bind(&Connection::connectionDidClose, this));
     275
     276    mach_port_t sendPort = m_sendPort;
     277    dispatch_source_set_cancel_handler(m_deadNameSource, ^{
     278        // Release our send right.
     279        mach_port_deallocate(mach_task_self(), sendPort);
     280    });
     281
     282    dispatch_resume(m_deadNameSource);
    255283}
    256284
  • trunk/Source/WebKit2/Platform/WorkQueue.h

    r133307 r141037  
    7575
    7676#if OS(DARWIN)
    77     enum MachPortEventType {
    78         // Fired when there is data on the given receive right.
    79         MachPortDataAvailable,
    80        
    81         // Fired when the receive right for this send right has been destroyed.
    82         MachPortDeadNameNotification
    83     };
    84    
    85     // Will execute the given function whenever the given mach port event fires.
    86     // Note that this will adopt the mach port and destroy it when the work queue is invalidated.
    87     void registerMachPortEventHandler(mach_port_t, MachPortEventType, const Function<void()>&);
    88     void unregisterMachPortEventHandler(mach_port_t);
     77    dispatch_queue_t dispatchQueue() const { return m_dispatchQueue; }
     78
    8979#elif OS(WINDOWS)
    9080    void registerHandle(HANDLE, const Function<void()>&);
     
    111101
    112102#if OS(DARWIN)
    113 #if HAVE(DISPATCH_H)
    114103    static void executeFunction(void*);
    115     Mutex m_eventSourcesMutex;
    116     class EventSource;
    117     HashMap<mach_port_t, EventSource*> m_eventSources;
    118104    dispatch_queue_t m_dispatchQueue;
    119 #endif
    120105#elif OS(WINDOWS)
    121106    class WorkItemWin : public ThreadSafeRefCounted<WorkItemWin> {
  • trunk/Source/WebKit2/Platform/mac/WorkQueueMac.cpp

    r130612 r141037  
    6666}
    6767
    68 class WorkQueue::EventSource {
    69 public:
    70     EventSource(MachPortEventType eventType, dispatch_source_t dispatchSource, const Function<void()>& function)
    71         : m_eventType(eventType)
    72         , m_dispatchSource(dispatchSource)
    73         , m_function(function)
    74     {
    75     }
    76    
    77     dispatch_source_t dispatchSource() const { return m_dispatchSource; }
    78    
    79     static void eventHandler(void* source)
    80     {
    81         EventSource* eventSource = static_cast<EventSource*>(source);
    82        
    83         eventSource->m_function();
    84     }
    85    
    86     static void cancelHandler(void* source)
    87     {
    88         EventSource* eventSource = static_cast<EventSource*>(source);
    89        
    90         mach_port_t machPort = dispatch_source_get_handle(eventSource->m_dispatchSource);
    91        
    92         switch (eventSource->m_eventType) {
    93         case MachPortDataAvailable:
    94             // Release our receive right.
    95             mach_port_mod_refs(mach_task_self(), machPort, MACH_PORT_RIGHT_RECEIVE, -1);
    96             break;
    97         case MachPortDeadNameNotification:
    98             // Release our send right.
    99             mach_port_deallocate(mach_task_self(), machPort);
    100             break;
    101         }
    102     }
    103    
    104     static void finalizeHandler(void* source)
    105     {
    106         EventSource* eventSource = static_cast<EventSource*>(source);
    107        
    108         delete eventSource;
    109     }
    110    
    111 private:
    112     MachPortEventType m_eventType;
    113    
    114     // This is a weak reference, since m_dispatchSource references the event source.
    115     dispatch_source_t m_dispatchSource;
    116 
    117     Function<void()> m_function;
    118 };
    119 
    120 void WorkQueue::registerMachPortEventHandler(mach_port_t machPort, MachPortEventType eventType, const Function<void()>& function)
    121 {
    122     ASSERT(machPort != MACH_PORT_NULL);
    123 
    124     dispatch_source_type_t sourceType = 0;
    125     switch (eventType) {
    126     case MachPortDataAvailable:
    127         sourceType = DISPATCH_SOURCE_TYPE_MACH_RECV;
    128         break;
    129     case MachPortDeadNameNotification:
    130         sourceType = DISPATCH_SOURCE_TYPE_MACH_SEND;
    131         break;
    132     }
    133    
    134     dispatch_source_t dispatchSource = dispatch_source_create(sourceType, machPort, 0, m_dispatchQueue);
    135    
    136     EventSource* eventSource = new EventSource(eventType, dispatchSource, function);
    137     dispatch_set_context(dispatchSource, eventSource);
    138    
    139     dispatch_source_set_event_handler_f(dispatchSource, &EventSource::eventHandler);
    140     dispatch_source_set_cancel_handler_f(dispatchSource, &EventSource::cancelHandler);
    141     dispatch_set_finalizer_f(dispatchSource, &EventSource::finalizeHandler);
    142    
    143     // Add the source to our set of sources.
    144     {
    145         MutexLocker locker(m_eventSourcesMutex);
    146        
    147         ASSERT(!m_eventSources.contains(machPort));
    148        
    149         m_eventSources.set(machPort, eventSource);
    150        
    151         // And start it!
    152         dispatch_resume(dispatchSource);
    153     }
    154 }
    155 
    156 void WorkQueue::unregisterMachPortEventHandler(mach_port_t machPort)
    157 {
    158     ASSERT(machPort != MACH_PORT_NULL);
    159    
    160     MutexLocker locker(m_eventSourcesMutex);
    161    
    162     HashMap<mach_port_t, EventSource*>::iterator it = m_eventSources.find(machPort);
    163     ASSERT(it != m_eventSources.end());
    164    
    165     ASSERT(m_eventSources.contains(machPort));
    166 
    167     EventSource* eventSource = it->value;
    168     // Cancel and release the source. It will be deleted in its finalize handler.
    169     dispatch_source_cancel(eventSource->dispatchSource());
    170     dispatch_release(eventSource->dispatchSource());
    171 
    172     m_eventSources.remove(it);   
    173 }
    174 
    17568void WorkQueue::platformInitialize(const char* name)
    17669{
     
    18174void WorkQueue::platformInvalidate()
    18275{
    183 #if !ASSERT_DISABLED
    184     MutexLocker locker(m_eventSourcesMutex);
    185     ASSERT(m_eventSources.isEmpty());
    186 #endif
    187 
    18876    dispatch_release(m_dispatchQueue);
    18977}
Note: See TracChangeset for help on using the changeset viewer.