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 |