Changeset 278395 in webkit
- Timestamp:
- Jun 2, 2021, 10:09:02 PM (5 years ago)
- Location:
- trunk/Source/WebKit
- Files:
-
- 5 edited
-
ChangeLog (modified) (1 diff)
-
Platform/IPC/Connection.cpp (modified) (4 diffs)
-
Platform/IPC/Connection.h (modified) (4 diffs)
-
UIProcess/mac/DisplayLink.cpp (modified) (9 diffs)
-
UIProcess/mac/DisplayLink.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r278394 r278395 1 2021-06-02 Chris Dumez <cdumez@apple.com> 2 3 Stop using a RefPtr<IPC::Connection> as HashMap key in DisplayLink 4 https://bugs.webkit.org/show_bug.cgi?id=226561 5 6 Reviewed by Simon Fraser. 7 8 Stop using a RefPtr<IPC::Connection> as HashMap key in DisplayLink. Using a RefPtr as key is suboptimal 9 and could leak to memory leaks. The reason this needed a RefPtr<IPC::Connection> was because we needed 10 to send IPC from a background thread. To support this, I have added a static IPC::Connection::send() 11 function that takes an IPC::Connection::UniqueID and that is thread safe. The function looks up the 12 IPC::Connection from its UniqueID and sends the IPC while still holding the lock. 13 14 As a result, DisplayLink can use IPC::Connection::UniqueID as key instead. 15 16 Note that I am planning to use the new static IPC::Connection::send() in other cases where we could 17 send IPC directly from a background thread instead of having to hop to the main thread to look up 18 the IPC::Connection from its UniqueID. StorageArea::dispatchEvents() is an example of where this will 19 be useful. 20 21 * Platform/IPC/Connection.cpp: 22 (IPC::Connection::Connection): 23 (IPC::Connection::~Connection): 24 * Platform/IPC/Connection.h: 25 (IPC::Connection::send): 26 * UIProcess/mac/DisplayLink.cpp: 27 (WebKit::DisplayLink::addObserver): 28 (WebKit::DisplayLink::removeObserver): 29 (WebKit::DisplayLink::removeObservers): 30 (WebKit::DisplayLink::removeInfoForConnectionIfPossible): 31 (WebKit::DisplayLink::incrementFullSpeedRequestClientCount): 32 (WebKit::DisplayLink::decrementFullSpeedRequestClientCount): 33 (WebKit::DisplayLink::setPreferredFramesPerSecond): 34 (WebKit::DisplayLink::notifyObserversDisplayWasRefreshed): 35 * UIProcess/mac/DisplayLink.h: 36 1 37 2021-06-02 Wenson Hsieh <wenson_hsieh@apple.com> 2 38 -
trunk/Source/WebKit/Platform/IPC/Connection.cpp
r277958 r278395 58 58 std::atomic<unsigned> UnboundedSynchronousIPCScope::unboundedSynchronousIPCCount = 0; 59 59 60 Lock Connection::s_connectionMapLock; 61 60 62 struct Connection::WaitForMessageState { 61 63 WaitForMessageState(MessageName messageName, uint64_t destinationID, OptionSet<WaitForOption> waitForOptions) … … 269 271 } 270 272 271 static HashMap<IPC::Connection::UniqueID, Connection*>& allConnections()273 HashMap<IPC::Connection::UniqueID, Connection*>& Connection::connectionMap() 272 274 { 273 275 static NeverDestroyed<HashMap<IPC::Connection::UniqueID, Connection*>> map; … … 292 294 { 293 295 ASSERT(RunLoop::isMain()); 294 allConnections().add(m_uniqueID, this); 296 297 { 298 Locker locker { s_connectionMapLock }; 299 connectionMap().add(m_uniqueID, this); 300 } 295 301 296 302 platformInitialize(identifier); … … 302 308 ASSERT(!isValid()); 303 309 304 allConnections().remove(m_uniqueID); 310 { 311 Locker locker { s_connectionMapLock }; 312 connectionMap().remove(m_uniqueID); 313 } 305 314 306 315 clearAsyncReplyHandlers(*this); 307 316 } 308 317 309 Connection* Connection::connection(UniqueID uniqueID) 318 // WTF_IGNORES_THREAD_SAFETY_ANALYSIS because this function accesses connectionMap() without locking. 319 // It is safe because this function is only called on the main thread and Connection objects are only 320 // constructed / destroyed on the main thread. 321 Connection* Connection::connection(UniqueID uniqueID) WTF_IGNORES_THREAD_SAFETY_ANALYSIS 310 322 { 311 323 ASSERT(RunLoop::isMain()); 312 return allConnections().get(uniqueID);324 return connectionMap().get(uniqueID); 313 325 } 314 326 -
trunk/Source/WebKit/Platform/IPC/Connection.h
r278253 r278395 244 244 template<typename T, typename C> uint64_t sendWithAsyncReply(T&& message, C&& completionHandler, uint64_t destinationID = 0, OptionSet<SendOption> = { }); // Thread-safe. 245 245 template<typename T> bool send(T&& message, uint64_t destinationID, OptionSet<SendOption> sendOptions = { }); // Thread-safe. 246 template<typename T> static bool send(UniqueID, T&& message, uint64_t destinationID, OptionSet<SendOption> sendOptions = { }); // Thread-safe. 247 246 248 // Sync senders should check the SendSyncResult for true/false in case they need to know if the result was really received. 247 249 // Sync senders should hold on to the SendSyncResult in case they reference the contents of the reply via DataRefererence / ArrayReference. … … 326 328 327 329 bool isIncomingMessagesThrottlingEnabled() const { return !!m_incomingMessagesThrottler; } 330 331 static HashMap<IPC::Connection::UniqueID, Connection*>& connectionMap() WTF_REQUIRES_LOCK(s_connectionMapLock); 328 332 329 333 std::unique_ptr<Decoder> waitForMessage(MessageName, uint64_t destinationID, Timeout, OptionSet<WaitForOption>); … … 383 387 }; 384 388 389 static Lock s_connectionMapLock; 385 390 Client& m_client; 386 391 UniqueID m_uniqueID; … … 514 519 515 520 return sendMessage(WTFMove(encoder), sendOptions); 521 } 522 523 template<typename T> 524 bool Connection::send(UniqueID connectionID, T&& message, uint64_t destinationID, OptionSet<SendOption> sendOptions) 525 { 526 Locker locker { s_connectionMapLock }; 527 auto* connection = connectionMap().get(connectionID); 528 if (!connection) 529 return false; 530 return connection->send(WTFMove(message), destinationID, sendOptions); 516 531 } 517 532 -
trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp
r278253 r278395 91 91 { 92 92 Locker locker { m_observersLock }; 93 m_observers.ensure( &connection, [] {93 m_observers.ensure(connection.uniqueID(), [] { 94 94 return ConnectionClientInfo { }; 95 95 }).iterator->value.observers.append({ observerID, preferredFramesPerSecond }); … … 112 112 Locker locker { m_observersLock }; 113 113 114 auto it = m_observers.find( &connection);114 auto it = m_observers.find(connection.uniqueID()); 115 115 if (it == m_observers.end()) 116 116 return; … … 137 137 138 138 Locker locker { m_observersLock }; 139 m_observers.remove( &connection);139 m_observers.remove(connection.uniqueID()); 140 140 141 141 // We do not stop the display link right away when |m_observers| becomes empty. Instead, we … … 146 146 void DisplayLink::removeInfoForConnectionIfPossible(IPC::Connection& connection) 147 147 { 148 auto it = m_observers.find( &connection);148 auto it = m_observers.find(connection.uniqueID()); 149 149 if (it == m_observers.end()) 150 150 return; … … 159 159 Locker locker { m_observersLock }; 160 160 161 auto& connectionInfo = m_observers.ensure( &connection, [] {161 auto& connectionInfo = m_observers.ensure(connection.uniqueID(), [] { 162 162 return ConnectionClientInfo { }; 163 163 }).iterator->value; … … 170 170 Locker locker { m_observersLock }; 171 171 172 auto it = m_observers.find( &connection);172 auto it = m_observers.find(connection.uniqueID()); 173 173 if (it == m_observers.end()) 174 174 return; … … 186 186 Locker locker { m_observersLock }; 187 187 188 auto it = m_observers.find( &connection);188 auto it = m_observers.find(connection.uniqueID()); 189 189 if (it == m_observers.end()) 190 190 return; … … 219 219 220 220 bool anyConnectionHadObservers = false; 221 for (auto& [connection , connectionInfo] : m_observers) {221 for (auto& [connectionID, connectionInfo] : m_observers) { 222 222 if (connectionInfo.observers.isEmpty()) 223 223 continue; … … 232 232 233 233 if (connectionInfo.fullSpeedUpdatesClientCount) { 234 connection->send(Messages::EventDispatcher::DisplayWasRefreshed(m_displayID, m_currentUpdate, mainThreadWantsUpdate), 0);234 IPC::Connection::send(connectionID, Messages::EventDispatcher::DisplayWasRefreshed(m_displayID, m_currentUpdate, mainThreadWantsUpdate), 0); 235 235 } else if (mainThreadWantsUpdate) 236 connection->send(Messages::WebProcess::DisplayWasRefreshed(m_displayID, m_currentUpdate), 0);236 IPC::Connection::send(connectionID, Messages::WebProcess::DisplayWasRefreshed(m_displayID, m_currentUpdate), 0); 237 237 } 238 238 -
trunk/Source/WebKit/UIProcess/mac/DisplayLink.h
r277958 r278395 28 28 #if HAVE(CVDISPLAYLINK) 29 29 30 #include "Connection.h" 30 31 #include "DisplayLinkObserverID.h" 31 32 #include <CoreVideo/CVDisplayLink.h> … … 85 86 CVDisplayLinkRef m_displayLink { nullptr }; 86 87 Lock m_observersLock; 87 HashMap< RefPtr<IPC::Connection>, ConnectionClientInfo> m_observers WTF_GUARDED_BY_LOCK(m_observersLock);88 HashMap<IPC::Connection::UniqueID, ConnectionClientInfo> m_observers WTF_GUARDED_BY_LOCK(m_observersLock); 88 89 WebCore::PlatformDisplayID m_displayID; 89 90 WebCore::FramesPerSecond m_displayNominalFramesPerSecond { 0 };
Note:
See TracChangeset
for help on using the changeset viewer.