transportlayerloopback.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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. // Original author: ekr@rtfm.com
  6. #ifndef transportlayerloopback_h__
  7. #define transportlayerloopback_h__
  8. #include "nspr.h"
  9. #include "prio.h"
  10. #include "prlock.h"
  11. #include <memory>
  12. #include <queue>
  13. #include "nsAutoPtr.h"
  14. #include "nsCOMPtr.h"
  15. #include "nsITimer.h"
  16. #include "m_cpp_utils.h"
  17. #include "transportflow.h"
  18. #include "transportlayer.h"
  19. // A simple loopback transport layer that is used for testing.
  20. namespace mozilla {
  21. class TransportLayerLoopback : public TransportLayer {
  22. public:
  23. TransportLayerLoopback() :
  24. peer_(nullptr),
  25. timer_(nullptr),
  26. packets_(),
  27. packets_lock_(nullptr),
  28. deliverer_(nullptr),
  29. combinePackets_(false) {}
  30. ~TransportLayerLoopback() {
  31. while (!packets_.empty()) {
  32. QueuedPacket *packet = packets_.front();
  33. packets_.pop();
  34. delete packet;
  35. }
  36. if (packets_lock_) {
  37. PR_DestroyLock(packets_lock_);
  38. }
  39. timer_->Cancel();
  40. deliverer_->Detach();
  41. }
  42. // Init
  43. nsresult Init();
  44. // Connect to the other side
  45. void Connect(TransportLayerLoopback* peer);
  46. // Disconnect
  47. void Disconnect() {
  48. TransportLayerLoopback *peer = peer_;
  49. peer_ = nullptr;
  50. if (peer) {
  51. peer->Disconnect();
  52. }
  53. }
  54. void CombinePackets(bool combine) { combinePackets_ = combine; }
  55. // Overrides for TransportLayer
  56. virtual TransportResult SendPacket(const unsigned char *data, size_t len);
  57. // Deliver queued packets
  58. void DeliverPackets();
  59. TRANSPORT_LAYER_ID("loopback")
  60. private:
  61. DISALLOW_COPY_ASSIGN(TransportLayerLoopback);
  62. // A queued packet
  63. class QueuedPacket {
  64. public:
  65. QueuedPacket() : data_(nullptr), len_(0) {}
  66. ~QueuedPacket() {
  67. delete [] data_;
  68. }
  69. void Assign(const unsigned char *data, size_t len) {
  70. data_ = new unsigned char[len];
  71. memcpy(static_cast<void *>(data_),
  72. static_cast<const void *>(data), len);
  73. len_ = len;
  74. }
  75. void Assign(const unsigned char *data1, size_t len1,
  76. const unsigned char *data2, size_t len2) {
  77. data_ = new unsigned char[len1 + len2];
  78. memcpy(static_cast<void *>(data_),
  79. static_cast<const void *>(data1), len1);
  80. memcpy(static_cast<void *>(data_ + len1),
  81. static_cast<const void *>(data2), len2);
  82. len_ = len1 + len2;
  83. }
  84. const unsigned char *data() const { return data_; }
  85. size_t len() const { return len_; }
  86. private:
  87. DISALLOW_COPY_ASSIGN(QueuedPacket);
  88. unsigned char *data_;
  89. size_t len_;
  90. };
  91. // A timer to deliver packets if some are available
  92. // Fires every 100 ms
  93. class Deliverer : public nsITimerCallback {
  94. public:
  95. explicit Deliverer(TransportLayerLoopback *layer) :
  96. layer_(layer) {}
  97. void Detach() {
  98. layer_ = nullptr;
  99. }
  100. NS_DECL_THREADSAFE_ISUPPORTS
  101. NS_DECL_NSITIMERCALLBACK
  102. private:
  103. virtual ~Deliverer() {
  104. }
  105. DISALLOW_COPY_ASSIGN(Deliverer);
  106. TransportLayerLoopback *layer_;
  107. };
  108. // Queue a packet for delivery
  109. nsresult QueuePacket(const unsigned char *data, size_t len);
  110. TransportLayerLoopback* peer_;
  111. nsCOMPtr<nsITimer> timer_;
  112. std::queue<QueuedPacket *> packets_;
  113. PRLock *packets_lock_;
  114. RefPtr<Deliverer> deliverer_;
  115. bool combinePackets_;
  116. };
  117. } // close namespace
  118. #endif