AutoClose.h 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  4. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef mozilla_net_AutoClose_h
  6. #define mozilla_net_AutoClose_h
  7. #include "nsCOMPtr.h"
  8. #include "mozilla/Mutex.h"
  9. namespace mozilla { namespace net {
  10. // Like an nsAutoPtr for XPCOM streams (e.g. nsIAsyncInputStream) and other
  11. // refcounted classes that need to have the Close() method called explicitly
  12. // before they are destroyed.
  13. template <typename T>
  14. class AutoClose
  15. {
  16. public:
  17. AutoClose() : mMutex("net::AutoClose.mMutex") { }
  18. ~AutoClose(){
  19. CloseAndRelease();
  20. }
  21. explicit operator bool()
  22. {
  23. MutexAutoLock lock(mMutex);
  24. return mPtr;
  25. }
  26. already_AddRefed<T> forget()
  27. {
  28. MutexAutoLock lock(mMutex);
  29. return mPtr.forget();
  30. }
  31. void takeOver(nsCOMPtr<T> & rhs)
  32. {
  33. already_AddRefed<T> other = rhs.forget();
  34. TakeOverInternal(&other);
  35. }
  36. void CloseAndRelease()
  37. {
  38. TakeOverInternal(nullptr);
  39. }
  40. private:
  41. void TakeOverInternal(already_AddRefed<T> *aOther)
  42. {
  43. nsCOMPtr<T> ptr;
  44. {
  45. MutexAutoLock lock(mMutex);
  46. ptr.swap(mPtr);
  47. if (aOther) {
  48. mPtr = *aOther;
  49. }
  50. }
  51. if (ptr) {
  52. ptr->Close();
  53. }
  54. }
  55. void operator=(const AutoClose<T> &) = delete;
  56. AutoClose(const AutoClose<T> &) = delete;
  57. nsCOMPtr<T> mPtr;
  58. Mutex mMutex;
  59. };
  60. } // namespace net
  61. } // namespace mozilla
  62. #endif // mozilla_net_AutoClose_h