Changeset 71080 in webkit
- Timestamp:
- Nov 1, 2010 5:09:19 PM (13 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r71079 r71080 1 2010-11-01 Martin Robinson <mrobinson@igalia.com> 2 3 Reviewed by Xan Lopez. 4 5 [Soup] Random crashes in http/tests/websocket/tests/workers/worker-handshake-challenge-randomness.html 6 https://bugs.webkit.org/show_bug.cgi?id=48805 7 8 Track active WebSocket handles via a sequential id. This ensures 9 that when a handle is reallocated into a recently used segment of 10 memory, it doesn't trigger a false positive in the code which ensures 11 the original handle is active. 12 13 No new tests. This test should stop crashing on the bots, proving the fix. 14 15 * platform/network/soup/SocketStreamHandle.h: 16 (WebCore::SocketStreamHandle::id): Added an m_id member and accessor 17 to SocketStreamHandle. 18 * platform/network/soup/SocketStreamHandleSoup.cpp: 19 (WebCore::getHandleFromId): Updated to work with HashMap of handle ids to 20 SocketStreamHandle*. 21 (WebCore::deactivateHandle): Ditto. 22 (WebCore::activateHandle): Ditto. 23 (WebCore::SocketStreamHandle::SocketStreamHandle): Ditto. 24 (WebCore::SocketStreamHandle::connected): Ditto. 25 (WebCore::SocketStreamHandle::readBytes): Ditto. 26 (WebCore::SocketStreamHandle::beginWaitingForSocketWritability): Ditto. 27 (WebCore::connectedCallback): Ditto. 28 (WebCore::readReadyCallback): Ditto. 29 (WebCore::writeReadyCallback): Ditto. 30 1 31 2010-11-01 Kent Tamura <tkent@chromium.org> 2 32 -
trunk/WebCore/platform/network/soup/SocketStreamHandle.h
r66986 r71080 52 52 void readBytes(signed long, GError*); 53 53 void writeReady(); 54 void* id() { return m_id; } 54 55 55 56 protected: … … 63 64 PlatformRefPtr<GSource> m_writeReadySource; 64 65 char* m_readBuffer; 66 void* m_id; 65 67 66 68 SocketStreamHandle(const KURL&, SocketStreamHandleClient*); -
trunk/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp
r66986 r71080 49 49 50 50 // These functions immediately call the similarly named SocketStreamHandle methods. 51 static void connectedCallback(GSocketClient*, GAsyncResult*, SocketStreamHandle*);52 static void readReadyCallback(GInputStream*, GAsyncResult*, SocketStreamHandle*);53 static gboolean writeReadyCallback(GSocket*, GIOCondition, SocketStreamHandle*);51 static void connectedCallback(GSocketClient*, GAsyncResult*, void*); 52 static void readReadyCallback(GInputStream*, GAsyncResult*, void*); 53 static gboolean writeReadyCallback(GSocket*, GIOCondition, void*); 54 54 55 55 // Having a list of active handles means that we do not have to worry about WebCore … … 57 57 // we just ignore it in the callback. We avoid a lot of extra checks and tricky 58 58 // situations this way. 59 static Vector<SocketStreamHandle*> gActiveHandles; 60 bool isActiveHandle(SocketStreamHandle* handle) 61 { 62 return gActiveHandles.find(handle) != notFound; 63 } 64 65 void deactivateHandle(SocketStreamHandle* handle) 66 { 67 size_t handleIndex = gActiveHandles.find(handle); 68 if (handleIndex != notFound) 69 gActiveHandles.remove(handleIndex); 59 static HashMap<void*, SocketStreamHandle*> gActiveHandles; 60 static SocketStreamHandle* getHandleFromId(void* id) 61 { 62 if (!gActiveHandles.contains(id)) 63 return 0; 64 return gActiveHandles.get(id); 65 } 66 67 static void deactivateHandle(SocketStreamHandle* handle) 68 { 69 gActiveHandles.remove(handle->id()); 70 } 71 72 static void* activateHandle(SocketStreamHandle* handle) 73 { 74 static gint currentHandleId = 0; 75 void* id = GINT_TO_POINTER(currentHandleId++); 76 gActiveHandles.set(id, handle); 77 return id; 70 78 } 71 79 … … 79 87 unsigned int port = url.hasPort() ? url.port() : 80; 80 88 81 gActiveHandles.append(this);89 m_id = activateHandle(this); 82 90 PlatformRefPtr<GSocketClient> socketClient = adoptPlatformRef(g_socket_client_new()); 83 91 g_socket_client_connect_to_host_async(socketClient.get(), url.host().utf8().data(), port, 0, 84 reinterpret_cast<GAsyncReadyCallback>(connectedCallback), this);92 reinterpret_cast<GAsyncReadyCallback>(connectedCallback), m_id); 85 93 } 86 94 … … 105 113 m_readBuffer = new char[READ_BUFFER_SIZE]; 106 114 g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0, 107 reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), this);115 reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), m_id); 108 116 109 117 // The client can close the handle, potentially removing the last reference. … … 132 140 if (m_inputStream) // The client may have closed the connection. 133 141 g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0, 134 reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), this);142 reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), m_id); 135 143 } 136 144 … … 216 224 m_writeReadySource = adoptPlatformRef(g_socket_create_source( 217 225 g_socket_connection_get_socket(m_socketConnection.get()), static_cast<GIOCondition>(G_IO_OUT), 0)); 218 g_source_set_callback(m_writeReadySource.get(), reinterpret_cast<GSourceFunc>(writeReadyCallback), this, 0);226 g_source_set_callback(m_writeReadySource.get(), reinterpret_cast<GSourceFunc>(writeReadyCallback), m_id, 0); 219 227 g_source_attach(m_writeReadySource.get(), 0); 220 228 } … … 229 237 } 230 238 231 static void connectedCallback(GSocketClient* client, GAsyncResult* result, SocketStreamHandle* handle)239 static void connectedCallback(GSocketClient* client, GAsyncResult* result, void* id) 232 240 { 233 241 // Always finish the connection, even if this SocketStreamHandle was deactivated earlier. … … 236 244 237 245 // The SocketStreamHandle has been deactivated, so just close the connection, ignoring errors. 238 if (!isActiveHandle(handle)) { 246 SocketStreamHandle* handle = getHandleFromId(id); 247 if (!handle) { 239 248 g_io_stream_close(G_IO_STREAM(socketConnection), 0, &error.outPtr()); 240 249 return; … … 244 253 } 245 254 246 static void readReadyCallback(GInputStream* stream, GAsyncResult* result, SocketStreamHandle* handle)255 static void readReadyCallback(GInputStream* stream, GAsyncResult* result, void* id) 247 256 { 248 257 // Always finish the read, even if this SocketStreamHandle was deactivated earlier. … … 250 259 gssize bytesRead = g_input_stream_read_finish(stream, result, &error.outPtr()); 251 260 252 if (!isActiveHandle(handle)) 253 return; 261 SocketStreamHandle* handle = getHandleFromId(id); 262 if (!handle) 263 return; 264 254 265 handle->readBytes(bytesRead, error.get()); 255 266 } 256 267 257 static gboolean writeReadyCallback(GSocket*, GIOCondition condition, SocketStreamHandle* handle) 258 { 259 if (!isActiveHandle(handle)) 268 static gboolean writeReadyCallback(GSocket*, GIOCondition condition, void* id) 269 { 270 SocketStreamHandle* handle = getHandleFromId(id); 271 if (!handle) 260 272 return FALSE; 261 273
Note: See TracChangeset
for help on using the changeset viewer.