1/* 2 * Copyright (C) 2013 Apple Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#if ENABLE(REMOTE_INSPECTOR) 27 28#ifndef RemoteInspectorDebuggableConnection_h 29#define RemoteInspectorDebuggableConnection_h 30 31#import "InspectorFrontendChannel.h" 32#import "RemoteInspectorDebuggable.h" 33#import <dispatch/dispatch.h> 34#import <mutex> 35#import <wtf/RetainPtr.h> 36#import <wtf/ThreadSafeRefCounted.h> 37 38OBJC_CLASS NSString; 39 40namespace Inspector { 41 42class RemoteInspectorBlock { 43public: 44 RemoteInspectorBlock(void (^task)()) 45 : m_task(Block_copy(task)) 46 { 47 } 48 49 RemoteInspectorBlock(const RemoteInspectorBlock& other) 50 : m_task(Block_copy(other.m_task)) 51 { 52 } 53 54 ~RemoteInspectorBlock() 55 { 56 Block_release(m_task); 57 } 58 59 RemoteInspectorBlock& operator=(const RemoteInspectorBlock& other) 60 { 61 void (^oldTask)() = m_task; 62 m_task = Block_copy(other.m_task); 63 Block_release(oldTask); 64 return *this; 65 } 66 67 void operator()() const 68 { 69 m_task(); 70 } 71 72private: 73 void (^m_task)(); 74}; 75 76typedef Vector<RemoteInspectorBlock> RemoteInspectorQueue; 77 78class RemoteInspectorDebuggableConnection final : public ThreadSafeRefCounted<RemoteInspectorDebuggableConnection>, public InspectorFrontendChannel { 79public: 80 RemoteInspectorDebuggableConnection(RemoteInspectorDebuggable*, NSString *connectionIdentifier, NSString *destination, RemoteInspectorDebuggable::DebuggableType); 81 virtual ~RemoteInspectorDebuggableConnection(); 82 83 NSString *destination() const; 84 NSString *connectionIdentifier() const; 85 unsigned identifier() const { return m_identifier; } 86 87 bool setup(); 88 89 void close(); 90 void closeFromDebuggable(); 91 92 void sendMessageToBackend(NSString *); 93 virtual bool sendMessageToFrontend(const String&) override; 94 95 std::mutex& queueMutex() { return m_queueMutex; } 96 RemoteInspectorQueue queue() const { return m_queue; } 97 void clearQueue() { m_queue.clear(); } 98 99private: 100 void dispatchAsyncOnDebuggable(void (^block)()); 101 102 void setupRunLoop(); 103 void teardownRunLoop(); 104 void queueTaskOnPrivateRunLoop(void (^block)()); 105 106 // This connection from the RemoteInspector singleton to the Debuggable 107 // can be used on multiple threads. So any access to the debuggable 108 // itself must take this mutex to ensure m_debuggable is valid. 109 std::mutex m_debuggableMutex; 110 111 // If a debuggable has a specific run loop it wants to evaluate on 112 // we setup our run loop sources on that specific run loop. 113 RetainPtr<CFRunLoopRef> m_runLoop; 114 RetainPtr<CFRunLoopSourceRef> m_runLoopSource; 115 RemoteInspectorQueue m_queue; 116 std::mutex m_queueMutex; 117 118 RemoteInspectorDebuggable* m_debuggable; 119 RetainPtr<NSString> m_connectionIdentifier; 120 RetainPtr<NSString> m_destination; 121 unsigned m_identifier; 122 bool m_connected; 123}; 124 125} // namespace Inspector 126 127#endif // RemoteInspectorDebuggableConnection_h 128 129#endif // ENABLE(REMOTE_INSPECTOR) 130