ChannelEventQueue.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2. */
  3. /* This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6. #include "nsISupports.h"
  7. #include "mozilla/net/ChannelEventQueue.h"
  8. #include "mozilla/Unused.h"
  9. #include "nsThreadUtils.h"
  10. #include "mozilla/Unused.h"
  11. namespace mozilla {
  12. namespace net {
  13. ChannelEvent*
  14. ChannelEventQueue::TakeEvent()
  15. {
  16. MutexAutoLock lock(mMutex);
  17. MOZ_ASSERT(mFlushing);
  18. if (mSuspended || mEventQueue.IsEmpty()) {
  19. return nullptr;
  20. }
  21. UniquePtr<ChannelEvent> event(Move(mEventQueue[0]));
  22. mEventQueue.RemoveElementAt(0);
  23. return event.release();
  24. }
  25. void
  26. ChannelEventQueue::FlushQueue()
  27. {
  28. // Events flushed could include destruction of channel (and our own
  29. // destructor) unless we make sure its refcount doesn't drop to 0 while this
  30. // method is running.
  31. nsCOMPtr<nsISupports> kungFuDeathGrip(mOwner);
  32. mozilla::Unused << kungFuDeathGrip; // Not used in this function
  33. // Prevent flushed events from flushing the queue recursively
  34. {
  35. MutexAutoLock lock(mMutex);
  36. mFlushing = true;
  37. }
  38. while (true) {
  39. UniquePtr<ChannelEvent> event(TakeEvent());
  40. if (!event) {
  41. break;
  42. }
  43. event->Run();
  44. }
  45. MutexAutoLock lock(mMutex);
  46. mFlushing = false;
  47. }
  48. void
  49. ChannelEventQueue::Resume()
  50. {
  51. MutexAutoLock lock(mMutex);
  52. // Resuming w/o suspend: error in debug mode, ignore in build
  53. MOZ_ASSERT(mSuspendCount > 0);
  54. if (mSuspendCount <= 0) {
  55. return;
  56. }
  57. if (!--mSuspendCount) {
  58. RefPtr<Runnable> event =
  59. NewRunnableMethod(this, &ChannelEventQueue::CompleteResume);
  60. if (mTargetThread) {
  61. mTargetThread->Dispatch(event.forget(), NS_DISPATCH_NORMAL);
  62. } else {
  63. MOZ_RELEASE_ASSERT(NS_IsMainThread());
  64. Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToCurrentThread(event.forget())));
  65. }
  66. }
  67. }
  68. nsresult
  69. ChannelEventQueue::RetargetDeliveryTo(nsIEventTarget* aTargetThread)
  70. {
  71. MOZ_RELEASE_ASSERT(NS_IsMainThread());
  72. MOZ_RELEASE_ASSERT(!mTargetThread);
  73. MOZ_RELEASE_ASSERT(aTargetThread);
  74. mTargetThread = do_QueryInterface(aTargetThread);
  75. MOZ_RELEASE_ASSERT(mTargetThread);
  76. return NS_OK;
  77. }
  78. } // namespace net
  79. } // namespace mozilla