| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 m_bridge.clear(); | 194 m_bridge.clear(); |
| 195 } | 195 } |
| 196 | 196 |
| 197 void WorkerThreadableWebSocketChannel::trace(Visitor* visitor) | 197 void WorkerThreadableWebSocketChannel::trace(Visitor* visitor) |
| 198 { | 198 { |
| 199 visitor->trace(m_bridge); | 199 visitor->trace(m_bridge); |
| 200 visitor->trace(m_workerClientWrapper); | 200 visitor->trace(m_workerClientWrapper); |
| 201 WebSocketChannel::trace(visitor); | 201 WebSocketChannel::trace(visitor); |
| 202 } | 202 } |
| 203 | 203 |
| 204 #if ENABLE(OILPAN) | 204 Peer::Peer(PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> clien
tWrapper, WorkerLoaderProxy& loaderProxy, PassRefPtrWillBeRawPtr<ThreadableWebSo
cketChannelSyncHelper> syncHelper) |
| 205 Peer::Peer(RawPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper, Worker
LoaderProxy& loaderProxy, ExecutionContext* context, const String& sourceURL, un
signed lineNumber, RawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper) | |
| 206 #else | |
| 207 Peer::Peer(PassRefPtr<WeakReference<Peer> > reference, PassRefPtr<ThreadableWebS
ocketChannelClientWrapper> clientWrapper, WorkerLoaderProxy& loaderProxy, Execut
ionContext* context, const String& sourceURL, unsigned lineNumber, PassRefPtr<Th
readableWebSocketChannelSyncHelper> syncHelper) | |
| 208 #endif | |
| 209 : m_workerClientWrapper(clientWrapper) | 205 : m_workerClientWrapper(clientWrapper) |
| 210 , m_loaderProxy(loaderProxy) | 206 , m_loaderProxy(loaderProxy) |
| 211 , m_mainWebSocketChannel(nullptr) | 207 , m_mainWebSocketChannel(nullptr) |
| 212 , m_syncHelper(syncHelper) | 208 , m_syncHelper(syncHelper) |
| 213 #if ENABLE(OILPAN) | 209 { |
| 214 , m_keepAlive(this) | 210 ASSERT(!isMainThread()); |
| 215 #else | 211 } |
| 216 , m_weakFactory(reference, this) | 212 |
| 217 #endif | 213 Peer::~Peer() |
| 214 { |
| 215 ASSERT(!isMainThread()); |
| 216 } |
| 217 |
| 218 PassOwnPtrWillBeRawPtr<Peer> Peer::create(PassRefPtrWillBeRawPtr<ThreadableWebSo
cketChannelClientWrapper> clientWrapper, WorkerLoaderProxy& loaderProxy, PassRef
PtrWillBeRawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper) |
| 219 { |
| 220 return adoptPtrWillBeNoop(new Peer(clientWrapper, loaderProxy, syncHelper)); |
| 221 } |
| 222 |
| 223 void Peer::initializeInternal(ExecutionContext* context, const String& sourceURL
, unsigned lineNumber) |
| 218 { | 224 { |
| 219 ASSERT(isMainThread()); | 225 ASSERT(isMainThread()); |
| 220 ASSERT(m_workerClientWrapper.get()); | |
| 221 | |
| 222 Document* document = toDocument(context); | 226 Document* document = toDocument(context); |
| 223 if (RuntimeEnabledFeatures::experimentalWebSocketEnabled()) { | 227 if (RuntimeEnabledFeatures::experimentalWebSocketEnabled()) { |
| 224 m_mainWebSocketChannel = NewWebSocketChannelImpl::create(document, this,
sourceURL, lineNumber); | 228 m_mainWebSocketChannel = NewWebSocketChannelImpl::create(document, this,
sourceURL, lineNumber); |
| 225 } else { | 229 } else { |
| 226 m_mainWebSocketChannel = MainThreadWebSocketChannel::create(document, th
is, sourceURL, lineNumber); | 230 m_mainWebSocketChannel = MainThreadWebSocketChannel::create(document, th
is, sourceURL, lineNumber); |
| 227 } | 231 } |
| 228 } | |
| 229 | |
| 230 Peer::~Peer() | |
| 231 { | |
| 232 ASSERT(isMainThread()); | |
| 233 } | |
| 234 | |
| 235 #if ENABLE(OILPAN) | |
| 236 void Peer::initialize(ExecutionContext* context, WeakMember<Peer>* reference, Wo
rkerLoaderProxy* loaderProxy, RawPtr<ThreadableWebSocketChannelClientWrapper> cl
ientWrapper, const String& sourceURLAtConnection, unsigned lineNumberAtConnectio
n, RawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper) | |
| 237 { | |
| 238 // The caller must call destroy() to free the peer. | |
| 239 *reference = new Peer(clientWrapper, *loaderProxy, context, sourceURLAtConne
ction, lineNumberAtConnection, syncHelper); | |
| 240 syncHelper->signalWorkerThread(); | |
| 241 } | |
| 242 #else | |
| 243 void Peer::initialize(ExecutionContext* context, PassRefPtr<WeakReference<Peer>
> reference, WorkerLoaderProxy* loaderProxy, PassRefPtr<ThreadableWebSocketChann
elClientWrapper> clientWrapper, const String& sourceURLAtConnection, unsigned li
neNumberAtConnection, PassRefPtr<ThreadableWebSocketChannelSyncHelper> prpSyncHe
lper) | |
| 244 { | |
| 245 RefPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = prpSyncHelper; | |
| 246 // The caller must call destroy() to free the peer. | |
| 247 new Peer(reference, clientWrapper, *loaderProxy, context, sourceURLAtConnect
ion, lineNumberAtConnection, syncHelper); | |
| 248 syncHelper->signalWorkerThread(); | |
| 249 } | |
| 250 #endif | |
| 251 | |
| 252 void Peer::destroy() | |
| 253 { | |
| 254 ASSERT(isMainThread()); | |
| 255 disconnect(); | |
| 256 | |
| 257 #if ENABLE(OILPAN) | |
| 258 m_keepAlive = nullptr; | |
| 259 m_syncHelper->signalWorkerThread(); | 232 m_syncHelper->signalWorkerThread(); |
| 260 m_syncHelper = nullptr; | |
| 261 #else | |
| 262 delete this; | |
| 263 #endif | |
| 264 } | 233 } |
| 265 | 234 |
| 266 void Peer::connect(const KURL& url, const String& protocol) | 235 void Peer::connect(const KURL& url, const String& protocol) |
| 267 { | 236 { |
| 268 ASSERT(isMainThread()); | 237 ASSERT(isMainThread()); |
| 269 ASSERT(m_syncHelper); | 238 ASSERT(m_syncHelper); |
| 270 if (!m_mainWebSocketChannel) { | 239 if (!m_mainWebSocketChannel) { |
| 271 m_syncHelper->setConnectRequestResult(false); | 240 m_syncHelper->setConnectRequestResult(false); |
| 272 } else { | 241 } else { |
| 273 bool connectRequestResult = m_mainWebSocketChannel->connect(url, protoco
l); | 242 bool connectRequestResult = m_mainWebSocketChannel->connect(url, protoco
l); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 ASSERT(m_syncHelper); | 299 ASSERT(m_syncHelper); |
| 331 if (!m_mainWebSocketChannel) | 300 if (!m_mainWebSocketChannel) |
| 332 return; | 301 return; |
| 333 m_mainWebSocketChannel->fail(reason, level, sourceURL, lineNumber); | 302 m_mainWebSocketChannel->fail(reason, level, sourceURL, lineNumber); |
| 334 } | 303 } |
| 335 | 304 |
| 336 void Peer::disconnect() | 305 void Peer::disconnect() |
| 337 { | 306 { |
| 338 ASSERT(isMainThread()); | 307 ASSERT(isMainThread()); |
| 339 ASSERT(m_syncHelper); | 308 ASSERT(m_syncHelper); |
| 340 if (!m_mainWebSocketChannel) | 309 if (m_mainWebSocketChannel) { |
| 341 return; | 310 m_mainWebSocketChannel->disconnect(); |
| 342 m_mainWebSocketChannel->disconnect(); | 311 m_mainWebSocketChannel = nullptr; |
| 343 m_mainWebSocketChannel = nullptr; | 312 } |
| 313 m_syncHelper->signalWorkerThread(); |
| 344 } | 314 } |
| 345 | 315 |
| 346 static void workerGlobalScopeDidConnect(ExecutionContext* context, PassRefPtrWil
lBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, const St
ring& subprotocol, const String& extensions) | 316 static void workerGlobalScopeDidConnect(ExecutionContext* context, PassRefPtrWil
lBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, const St
ring& subprotocol, const String& extensions) |
| 347 { | 317 { |
| 348 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 318 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 349 workerClientWrapper->didConnect(subprotocol, extensions); | 319 workerClientWrapper->didConnect(subprotocol, extensions); |
| 350 } | 320 } |
| 351 | 321 |
| 352 void Peer::didConnect(const String& subprotocol, const String& extensions) | 322 void Peer::didConnect(const String& subprotocol, const String& extensions) |
| 353 { | 323 { |
| 354 ASSERT(isMainThread()); | 324 ASSERT(isMainThread()); |
| 355 // It is important to seprate task creation from posting | 325 // It is important to seprate task creation from posting |
| 356 // the task. See the above comment. | 326 // the task. See the above comment. |
| 357 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope
DidConnect, m_workerClientWrapper.get(), subprotocol, extensions); | 327 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope
DidConnect, m_workerClientWrapper, subprotocol, extensions); |
| 358 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); | 328 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); |
| 359 } | 329 } |
| 360 | 330 |
| 361 static void workerGlobalScopeDidReceiveMessage(ExecutionContext* context, PassRe
fPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, c
onst String& message) | 331 static void workerGlobalScopeDidReceiveMessage(ExecutionContext* context, PassRe
fPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, c
onst String& message) |
| 362 { | 332 { |
| 363 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 333 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 364 workerClientWrapper->didReceiveMessage(message); | 334 workerClientWrapper->didReceiveMessage(message); |
| 365 } | 335 } |
| 366 | 336 |
| 367 void Peer::didReceiveMessage(const String& message) | 337 void Peer::didReceiveMessage(const String& message) |
| 368 { | 338 { |
| 369 ASSERT(isMainThread()); | 339 ASSERT(isMainThread()); |
| 370 // It is important to seprate task creation from posting | 340 // It is important to seprate task creation from posting |
| 371 // the task. See the above comment. | 341 // the task. See the above comment. |
| 372 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope
DidReceiveMessage, m_workerClientWrapper.get(), message); | 342 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope
DidReceiveMessage, m_workerClientWrapper, message); |
| 373 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); | 343 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); |
| 374 } | 344 } |
| 375 | 345 |
| 376 static void workerGlobalScopeDidReceiveBinaryData(ExecutionContext* context, Pas
sRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper
, PassOwnPtr<Vector<char> > binaryData) | 346 static void workerGlobalScopeDidReceiveBinaryData(ExecutionContext* context, Pas
sRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper
, PassOwnPtr<Vector<char> > binaryData) |
| 377 { | 347 { |
| 378 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 348 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 379 workerClientWrapper->didReceiveBinaryData(binaryData); | 349 workerClientWrapper->didReceiveBinaryData(binaryData); |
| 380 } | 350 } |
| 381 | 351 |
| 382 void Peer::didReceiveBinaryData(PassOwnPtr<Vector<char> > binaryData) | 352 void Peer::didReceiveBinaryData(PassOwnPtr<Vector<char> > binaryData) |
| 383 { | 353 { |
| 384 ASSERT(isMainThread()); | 354 ASSERT(isMainThread()); |
| 385 // It is important to seprate task creation from posting | 355 // It is important to seprate task creation from posting |
| 386 // the task. See the above comment. | 356 // the task. See the above comment. |
| 387 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope
DidReceiveBinaryData, m_workerClientWrapper.get(), binaryData); | 357 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope
DidReceiveBinaryData, m_workerClientWrapper, binaryData); |
| 388 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); | 358 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); |
| 389 } | 359 } |
| 390 | 360 |
| 391 static void workerGlobalScopeDidConsumeBufferedAmount(ExecutionContext* context,
PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWra
pper, unsigned long consumed) | 361 static void workerGlobalScopeDidConsumeBufferedAmount(ExecutionContext* context,
PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWra
pper, unsigned long consumed) |
| 392 { | 362 { |
| 393 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 363 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 394 workerClientWrapper->didConsumeBufferedAmount(consumed); | 364 workerClientWrapper->didConsumeBufferedAmount(consumed); |
| 395 } | 365 } |
| 396 | 366 |
| 397 void Peer::didConsumeBufferedAmount(unsigned long consumed) | 367 void Peer::didConsumeBufferedAmount(unsigned long consumed) |
| 398 { | 368 { |
| 399 ASSERT(isMainThread()); | 369 ASSERT(isMainThread()); |
| 400 // It is important to seprate task creation from posting | 370 // It is important to seprate task creation from posting |
| 401 // the task. See the above comment. | 371 // the task. See the above comment. |
| 402 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope
DidConsumeBufferedAmount, m_workerClientWrapper.get(), consumed); | 372 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope
DidConsumeBufferedAmount, m_workerClientWrapper, consumed); |
| 403 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); | 373 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); |
| 404 } | 374 } |
| 405 | 375 |
| 406 static void workerGlobalScopeDidStartClosingHandshake(ExecutionContext* context,
PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWra
pper) | 376 static void workerGlobalScopeDidStartClosingHandshake(ExecutionContext* context,
PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWra
pper) |
| 407 { | 377 { |
| 408 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 378 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 409 workerClientWrapper->didStartClosingHandshake(); | 379 workerClientWrapper->didStartClosingHandshake(); |
| 410 } | 380 } |
| 411 | 381 |
| 412 void Peer::didStartClosingHandshake() | 382 void Peer::didStartClosingHandshake() |
| 413 { | 383 { |
| 414 ASSERT(isMainThread()); | 384 ASSERT(isMainThread()); |
| 415 // It is important to seprate task creation from posting | 385 // It is important to seprate task creation from posting |
| 416 // the task. See the above comment. | 386 // the task. See the above comment. |
| 417 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope
DidStartClosingHandshake, m_workerClientWrapper.get()); | 387 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope
DidStartClosingHandshake, m_workerClientWrapper); |
| 418 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); | 388 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); |
| 419 } | 389 } |
| 420 | 390 |
| 421 static void workerGlobalScopeDidClose(ExecutionContext* context, PassRefPtrWillB
eRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, WebSocketC
hannelClient::ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsig
ned short code, const String& reason) | 391 static void workerGlobalScopeDidClose(ExecutionContext* context, PassRefPtrWillB
eRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, WebSocketC
hannelClient::ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsig
ned short code, const String& reason) |
| 422 { | 392 { |
| 423 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 393 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 424 workerClientWrapper->didClose(closingHandshakeCompletion, code, reason); | 394 workerClientWrapper->didClose(closingHandshakeCompletion, code, reason); |
| 425 } | 395 } |
| 426 | 396 |
| 427 void Peer::didClose(ClosingHandshakeCompletionStatus closingHandshakeCompletion,
unsigned short code, const String& reason) | 397 void Peer::didClose(ClosingHandshakeCompletionStatus closingHandshakeCompletion,
unsigned short code, const String& reason) |
| 428 { | 398 { |
| 429 ASSERT(isMainThread()); | 399 ASSERT(isMainThread()); |
| 430 m_mainWebSocketChannel = nullptr; | 400 m_mainWebSocketChannel = nullptr; |
| 431 // It is important to seprate task creation from posting | 401 // It is important to seprate task creation from posting |
| 432 // the task. See the above comment. | 402 // the task. See the above comment. |
| 433 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope
DidClose, m_workerClientWrapper.get(), closingHandshakeCompletion, code, reason)
; | 403 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope
DidClose, m_workerClientWrapper, closingHandshakeCompletion, code, reason); |
| 434 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); | 404 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); |
| 435 } | 405 } |
| 436 | 406 |
| 437 static void workerGlobalScopeDidReceiveMessageError(ExecutionContext* context, P
assRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapp
er) | 407 static void workerGlobalScopeDidReceiveMessageError(ExecutionContext* context, P
assRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapp
er) |
| 438 { | 408 { |
| 439 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 409 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 440 workerClientWrapper->didReceiveMessageError(); | 410 workerClientWrapper->didReceiveMessageError(); |
| 441 } | 411 } |
| 442 | 412 |
| 443 void Peer::didReceiveMessageError() | 413 void Peer::didReceiveMessageError() |
| 444 { | 414 { |
| 445 ASSERT(isMainThread()); | 415 ASSERT(isMainThread()); |
| 446 // It is important to seprate task creation from posting | 416 // It is important to seprate task creation from posting |
| 447 // the task. See the above comment. | 417 // the task. See the above comment. |
| 448 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope
DidReceiveMessageError, m_workerClientWrapper.get()); | 418 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope
DidReceiveMessageError, m_workerClientWrapper); |
| 449 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); | 419 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); |
| 450 } | 420 } |
| 451 | 421 |
| 452 void Peer::trace(Visitor* visitor) | 422 void Peer::trace(Visitor* visitor) |
| 453 { | 423 { |
| 454 visitor->trace(m_workerClientWrapper); | 424 visitor->trace(m_workerClientWrapper); |
| 455 visitor->trace(m_mainWebSocketChannel); | 425 visitor->trace(m_mainWebSocketChannel); |
| 456 visitor->trace(m_syncHelper); | 426 visitor->trace(m_syncHelper); |
| 457 WebSocketChannelClient::trace(visitor); | 427 WebSocketChannelClient::trace(visitor); |
| 458 } | 428 } |
| 459 | 429 |
| 460 Bridge::Bridge(PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> w
orkerClientWrapper, WorkerGlobalScope& workerGlobalScope) | 430 Bridge::Bridge(PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> w
orkerClientWrapper, WorkerGlobalScope& workerGlobalScope) |
| 461 : m_workerClientWrapper(workerClientWrapper) | 431 : m_workerClientWrapper(workerClientWrapper) |
| 462 , m_workerGlobalScope(workerGlobalScope) | 432 , m_workerGlobalScope(workerGlobalScope) |
| 463 , m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy()) | 433 , m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy()) |
| 464 , m_syncHelper(nullptr) | 434 , m_syncHelper(nullptr) |
| 465 , m_peer(nullptr) | 435 , m_peer(Peer::create(m_workerClientWrapper, m_loaderProxy, m_syncHelper)) |
| 466 { | 436 { |
| 467 ASSERT(m_workerClientWrapper.get()); | 437 ASSERT(m_workerClientWrapper.get()); |
| 468 } | 438 } |
| 469 | 439 |
| 470 Bridge::~Bridge() | 440 Bridge::~Bridge() |
| 471 { | 441 { |
| 472 ASSERT(hasTerminatedPeer()); | 442 ASSERT(!hasPeer()); |
| 473 } | 443 } |
| 474 | 444 |
| 475 void Bridge::initialize(const String& sourceURL, unsigned lineNumber) | 445 void Bridge::initialize(const String& sourceURL, unsigned lineNumber) |
| 476 { | 446 { |
| 477 #if !ENABLE(OILPAN) | |
| 478 RefPtr<WeakReference<Peer> > reference = WeakReference<Peer>::createUnbound(
); | |
| 479 m_peer = WeakPtr<Peer>(reference); | |
| 480 #endif | |
| 481 | |
| 482 RefPtrWillBeRawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = Thread
ableWebSocketChannelSyncHelper::create(adoptPtr(blink::Platform::current()->crea
teWaitableEvent())); | 447 RefPtrWillBeRawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = Thread
ableWebSocketChannelSyncHelper::create(adoptPtr(blink::Platform::current()->crea
teWaitableEvent())); |
| 483 // This pointer is guaranteed to be valid until we call terminatePeer. | 448 // This pointer is guaranteed to be valid until we call terminatePeer. |
| 484 m_syncHelper = syncHelper.get(); | 449 m_syncHelper = syncHelper.get(); |
| 485 | 450 |
| 486 RefPtrWillBeRawPtr<Bridge> protect(this); | 451 RefPtrWillBeRawPtr<Bridge> protect(this); |
| 487 #if ENABLE(OILPAN) | |
| 488 // In order to assure all temporary objects to be destroyed before | 452 // In order to assure all temporary objects to be destroyed before |
| 489 // posting the task, we separate task creation and posting. | 453 // posting the task, we separate task creation and posting. |
| 490 // In other words, it is dangerous to have a complicated expression | 454 // In other words, it is dangerous to have a complicated expression |
| 491 // as a waitForMethodCompletion argument. | 455 // as a waitForMethodCompletion argument. |
| 492 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&Peer::initialize,
&m_peer, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), s
ourceURL, lineNumber, syncHelper.get()); | 456 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&Peer::initialize,
AllowCrossThreadAccess(m_peer.get()), sourceURL, lineNumber); |
| 493 #else | |
| 494 // See the above comment. | |
| 495 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&Peer::initialize,
reference, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(),
sourceURL, lineNumber, syncHelper.get()); | |
| 496 #endif | |
| 497 if (!waitForMethodCompletion(task.release())) { | 457 if (!waitForMethodCompletion(task.release())) { |
| 498 // The worker thread has been signalled to shutdown before method comple
tion. | 458 // The worker thread has been signalled to shutdown before method comple
tion. |
| 499 disconnect(); | 459 disconnect(); |
| 500 } | 460 } |
| 501 } | 461 } |
| 502 | 462 |
| 503 bool Bridge::connect(const KURL& url, const String& protocol) | 463 bool Bridge::connect(const KURL& url, const String& protocol) |
| 504 { | 464 { |
| 505 if (hasTerminatedPeer()) | 465 if (!hasPeer()) |
| 506 return false; | 466 return false; |
| 507 | 467 |
| 508 RefPtrWillBeRawPtr<Bridge> protect(this); | 468 RefPtrWillBeRawPtr<Bridge> protect(this); |
| 509 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::connect, m_peer, u
rl, protocol))) | 469 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::connect, m_peer.ge
t(), url, protocol))) |
| 510 return false; | 470 return false; |
| 511 | 471 |
| 512 return m_syncHelper->connectRequestResult(); | 472 return m_syncHelper->connectRequestResult(); |
| 513 } | 473 } |
| 514 | 474 |
| 515 WebSocketChannel::SendResult Bridge::send(const String& message) | 475 WebSocketChannel::SendResult Bridge::send(const String& message) |
| 516 { | 476 { |
| 517 if (hasTerminatedPeer()) | 477 if (!hasPeer()) |
| 518 return WebSocketChannel::SendFail; | 478 return WebSocketChannel::SendFail; |
| 519 | 479 |
| 520 RefPtrWillBeRawPtr<Bridge> protect(this); | 480 RefPtrWillBeRawPtr<Bridge> protect(this); |
| 521 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::send, m_peer, mess
age))) | 481 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::send, m_peer.get()
, message))) |
| 522 return WebSocketChannel::SendFail; | 482 return WebSocketChannel::SendFail; |
| 523 | 483 |
| 524 return m_syncHelper->sendRequestResult(); | 484 return m_syncHelper->sendRequestResult(); |
| 525 } | 485 } |
| 526 | 486 |
| 527 WebSocketChannel::SendResult Bridge::send(const ArrayBuffer& binaryData, unsigne
d byteOffset, unsigned byteLength) | 487 WebSocketChannel::SendResult Bridge::send(const ArrayBuffer& binaryData, unsigne
d byteOffset, unsigned byteLength) |
| 528 { | 488 { |
| 529 if (hasTerminatedPeer()) | 489 if (!hasPeer()) |
| 530 return WebSocketChannel::SendFail; | 490 return WebSocketChannel::SendFail; |
| 531 | 491 |
| 532 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied
into Vector<char>. | 492 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied
into Vector<char>. |
| 533 OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength)); | 493 OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength)); |
| 534 if (binaryData.byteLength()) | 494 if (binaryData.byteLength()) |
| 535 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO
ffset, byteLength); | 495 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO
ffset, byteLength); |
| 536 | 496 |
| 537 RefPtrWillBeRawPtr<Bridge> protect(this); | 497 RefPtrWillBeRawPtr<Bridge> protect(this); |
| 538 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::sendArrayBuffer, m
_peer, data.release()))) | 498 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::sendArrayBuffer, m
_peer.get(), data.release()))) |
| 539 return WebSocketChannel::SendFail; | 499 return WebSocketChannel::SendFail; |
| 540 | 500 |
| 541 return m_syncHelper->sendRequestResult(); | 501 return m_syncHelper->sendRequestResult(); |
| 542 } | 502 } |
| 543 | 503 |
| 544 WebSocketChannel::SendResult Bridge::send(PassRefPtr<BlobDataHandle> data) | 504 WebSocketChannel::SendResult Bridge::send(PassRefPtr<BlobDataHandle> data) |
| 545 { | 505 { |
| 546 if (hasTerminatedPeer()) | 506 if (!hasPeer()) |
| 547 return WebSocketChannel::SendFail; | 507 return WebSocketChannel::SendFail; |
| 548 | 508 |
| 549 RefPtrWillBeRawPtr<Bridge> protect(this); | 509 RefPtrWillBeRawPtr<Bridge> protect(this); |
| 550 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::sendBlob, m_peer,
data))) | 510 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::sendBlob, m_peer.g
et(), data))) |
| 551 return WebSocketChannel::SendFail; | 511 return WebSocketChannel::SendFail; |
| 552 | 512 |
| 553 return m_syncHelper->sendRequestResult(); | 513 return m_syncHelper->sendRequestResult(); |
| 554 } | 514 } |
| 555 | 515 |
| 556 void Bridge::close(int code, const String& reason) | 516 void Bridge::close(int code, const String& reason) |
| 557 { | 517 { |
| 558 if (hasTerminatedPeer()) | 518 if (!hasPeer()) |
| 559 return; | 519 return; |
| 560 | 520 |
| 561 m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::close, m_peer, c
ode, reason)); | 521 m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::close, m_peer.ge
t(), code, reason)); |
| 562 } | 522 } |
| 563 | 523 |
| 564 void Bridge::fail(const String& reason, MessageLevel level, const String& source
URL, unsigned lineNumber) | 524 void Bridge::fail(const String& reason, MessageLevel level, const String& source
URL, unsigned lineNumber) |
| 565 { | 525 { |
| 566 if (hasTerminatedPeer()) | 526 if (!hasPeer()) |
| 567 return; | 527 return; |
| 568 | 528 |
| 569 m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::fail, m_peer, re
ason, level, sourceURL, lineNumber)); | 529 m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::fail, m_peer.get
(), reason, level, sourceURL, lineNumber)); |
| 570 } | 530 } |
| 571 | 531 |
| 572 void Bridge::disconnect() | 532 void Bridge::disconnect() |
| 573 { | 533 { |
| 574 if (hasTerminatedPeer()) | 534 if (!hasPeer()) |
| 575 return; | 535 return; |
| 576 | 536 |
| 577 clearClientWrapper(); | 537 waitForMethodCompletion(createCrossThreadTask(&Peer::disconnect, m_peer.get(
))); |
| 578 terminatePeer(); | 538 // Here |m_peer| is detached from the main thread and we can delete it. |
| 579 } | |
| 580 | 539 |
| 581 void Bridge::clearClientWrapper() | 540 m_peer = nullptr; |
| 582 { | 541 m_syncHelper = nullptr; |
| 583 m_workerClientWrapper->clearClient(); | 542 // We won't use this any more. |
| 543 m_workerGlobalScope.clear(); |
| 584 } | 544 } |
| 585 | 545 |
| 586 // Caller of this function should hold a reference to the bridge, because this f
unction may call WebSocket::didClose() in the end, | 546 // Caller of this function should hold a reference to the bridge, because this f
unction may call WebSocket::didClose() in the end, |
| 587 // which causes the bridge to get disconnected from the WebSocket and deleted if
there is no other reference. | 547 // which causes the bridge to get disconnected from the WebSocket and deleted if
there is no other reference. |
| 588 bool Bridge::waitForMethodCompletion(PassOwnPtr<ExecutionContextTask> task) | 548 bool Bridge::waitForMethodCompletion(PassOwnPtr<ExecutionContextTask> task) |
| 589 { | 549 { |
| 590 ASSERT(m_workerGlobalScope); | 550 ASSERT(m_workerGlobalScope); |
| 591 ASSERT(m_syncHelper); | 551 ASSERT(m_syncHelper); |
| 592 | 552 |
| 593 m_loaderProxy.postTaskToLoader(task); | 553 m_loaderProxy.postTaskToLoader(task); |
| 594 | 554 |
| 595 // We wait for the syncHelper event even if a shutdown event is fired. | 555 // We wait for the syncHelper event even if a shutdown event is fired. |
| 596 // See https://codereview.chromium.org/267323004/#msg43 for why we need to w
ait this. | 556 // See https://codereview.chromium.org/267323004/#msg43 for why we need to w
ait this. |
| 597 Vector<blink::WebWaitableEvent*> events; | 557 Vector<blink::WebWaitableEvent*> events; |
| 598 events.append(m_syncHelper->event()); | 558 events.append(m_syncHelper->event()); |
| 599 ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack); | 559 ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack); |
| 600 blink::Platform::current()->waitMultipleEvents(events); | 560 blink::Platform::current()->waitMultipleEvents(events); |
| 601 // This is checking whether a shutdown event is fired or not. | 561 // This is checking whether a shutdown event is fired or not. |
| 602 return !m_workerGlobalScope->thread()->terminated(); | 562 return !m_workerGlobalScope->thread()->terminated(); |
| 603 } | 563 } |
| 604 | 564 |
| 605 void Bridge::terminatePeer() | |
| 606 { | |
| 607 ASSERT(!hasTerminatedPeer()); | |
| 608 | |
| 609 #if ENABLE(OILPAN) | |
| 610 // The worker thread has to wait for the main thread to complete Peer::destr
oy, | |
| 611 // because the worker thread has to make sure that the main thread does not
have any | |
| 612 // references to on-heap objects allocated in the thread heap of the worker
thread | |
| 613 // before the worker thread shuts down. | |
| 614 waitForMethodCompletion(createCrossThreadTask(&Peer::destroy, m_peer)); | |
| 615 #else | |
| 616 m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::destroy, m_peer)
); | |
| 617 #endif | |
| 618 | |
| 619 // Peer::destroy() deletes m_peer and then m_syncHelper will be released. | |
| 620 // We must not touch m_syncHelper any more. | |
| 621 m_syncHelper = nullptr; | |
| 622 | |
| 623 // We won't use this any more. | |
| 624 m_workerGlobalScope = nullptr; | |
| 625 } | |
| 626 | |
| 627 void Bridge::trace(Visitor* visitor) | 565 void Bridge::trace(Visitor* visitor) |
| 628 { | 566 { |
| 629 visitor->trace(m_workerClientWrapper); | 567 visitor->trace(m_workerClientWrapper); |
| 630 visitor->trace(m_workerGlobalScope); | 568 visitor->trace(m_workerGlobalScope); |
| 631 visitor->trace(m_syncHelper); | 569 visitor->trace(m_syncHelper); |
| 632 visitor->trace(m_peer); | 570 visitor->trace(m_peer); |
| 633 } | 571 } |
| 634 | 572 |
| 635 } // namespace blink | 573 } // namespace blink |
| OLD | NEW |