Changeset 71119 in webkit
- Timestamp:
- Nov 2, 2010 8:52:36 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r71117 r71119 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-02 Csaba Osztrogonác <ossy@webkit.org> 2 32 -
trunk/WebCore/platform/network/soup/SocketStreamHandle.h
r71091 r71119 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
r71091 r71119 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 // The first id cannot be 0, because it conflicts with the HashMap emptyValue. 75 static gint currentHandleId = 1; 76 void* id = GINT_TO_POINTER(currentHandleId++); 77 gActiveHandles.set(id, handle); 78 return id; 70 79 } 71 80 … … 79 88 unsigned int port = url.hasPort() ? url.port() : 80; 80 89 81 gActiveHandles.append(this);90 m_id = activateHandle(this); 82 91 PlatformRefPtr<GSocketClient> socketClient = adoptPlatformRef(g_socket_client_new()); 83 92 g_socket_client_connect_to_host_async(socketClient.get(), url.host().utf8().data(), port, 0, 84 reinterpret_cast<GAsyncReadyCallback>(connectedCallback), this);93 reinterpret_cast<GAsyncReadyCallback>(connectedCallback), m_id); 85 94 } 86 95 … … 105 114 m_readBuffer = new char[READ_BUFFER_SIZE]; 106 115 g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0, 107 reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), this);116 reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), m_id); 108 117 109 118 // The client can close the handle, potentially removing the last reference. … … 132 141 if (m_inputStream) // The client may have closed the connection. 133 142 g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0, 134 reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), this);143 reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), m_id); 135 144 } 136 145 … … 216 225 m_writeReadySource = adoptPlatformRef(g_socket_create_source( 217 226 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);227 g_source_set_callback(m_writeReadySource.get(), reinterpret_cast<GSourceFunc>(writeReadyCallback), m_id, 0); 219 228 g_source_attach(m_writeReadySource.get(), 0); 220 229 } … … 229 238 } 230 239 231 static void connectedCallback(GSocketClient* client, GAsyncResult* result, SocketStreamHandle* handle)240 static void connectedCallback(GSocketClient* client, GAsyncResult* result, void* id) 232 241 { 233 242 // Always finish the connection, even if this SocketStreamHandle was deactivated earlier. … … 236 245 237 246 // The SocketStreamHandle has been deactivated, so just close the connection, ignoring errors. 238 if (!isActiveHandle(handle)) { 247 SocketStreamHandle* handle = getHandleFromId(id); 248 if (!handle) { 239 249 g_io_stream_close(G_IO_STREAM(socketConnection), 0, &error.outPtr()); 240 250 return; … … 244 254 } 245 255 246 static void readReadyCallback(GInputStream* stream, GAsyncResult* result, SocketStreamHandle* handle)256 static void readReadyCallback(GInputStream* stream, GAsyncResult* result, void* id) 247 257 { 248 258 // Always finish the read, even if this SocketStreamHandle was deactivated earlier. … … 250 260 gssize bytesRead = g_input_stream_read_finish(stream, result, &error.outPtr()); 251 261 252 if (!isActiveHandle(handle)) 253 return; 262 SocketStreamHandle* handle = getHandleFromId(id); 263 if (!handle) 264 return; 265 254 266 handle->readBytes(bytesRead, error.get()); 255 267 } 256 268 257 static gboolean writeReadyCallback(GSocket*, GIOCondition condition, SocketStreamHandle* handle) 258 { 259 if (!isActiveHandle(handle)) 269 static gboolean writeReadyCallback(GSocket*, GIOCondition condition, void* id) 270 { 271 SocketStreamHandle* handle = getHandleFromId(id); 272 if (!handle) 260 273 return FALSE; 261 274
Note: See TracChangeset
for help on using the changeset viewer.