Backed out changeset b71c8c052463 (bug 1943846) for causing mass failures. CLOSED...
[gecko.git] / netwerk / sctp / datachannel / DataChannel.h
blobb9671d4a8f8208d8dc72d84d0ebc5cd66d70f967
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef NETWERK_SCTP_DATACHANNEL_DATACHANNEL_H_
8 #define NETWERK_SCTP_DATACHANNEL_DATACHANNEL_H_
10 #include <memory>
11 #include <string>
12 #include <vector>
13 #include <errno.h>
14 #include "nsISupports.h"
15 #include "nsCOMPtr.h"
16 #include "mozilla/UniquePtr.h"
17 #include "mozilla/WeakPtr.h"
18 #include "nsString.h"
19 #include "nsThreadUtils.h"
20 #include "nsTArray.h"
21 #include "nsDeque.h"
22 #include "mozilla/dom/Blob.h"
23 #include "mozilla/Mutex.h"
24 #include "DataChannelProtocol.h"
25 #include "DataChannelListener.h"
26 #include "mozilla/net/NeckoTargetHolder.h"
28 #include "transport/sigslot.h"
29 #include "transport/transportlayer.h" // For TransportLayer::State
31 #ifndef EALREADY
32 # define EALREADY WSAEALREADY
33 #endif
35 extern "C" {
36 struct socket;
37 struct sctp_rcvinfo;
40 namespace mozilla {
42 class DataChannelConnection;
43 class DataChannel;
44 class DataChannelOnMessageAvailable;
45 class MediaPacket;
46 class MediaTransportHandler;
47 namespace dom {
48 struct RTCStatsCollection;
51 enum class DataChannelState { Connecting, Open, Closing, Closed };
52 enum class DataChannelConnectionState { Connecting, Open, Closed };
53 enum class DataChannelReliabilityPolicy {
54 Reliable,
55 LimitedRetransmissions,
56 LimitedLifetime
59 // For sending outgoing messages.
60 // This class only holds a reference to the data and the info structure but does
61 // not copy it.
62 class OutgoingMsg {
63 public:
64 OutgoingMsg(struct sctp_sendv_spa& info, Span<const uint8_t> data);
66 void Advance(size_t offset);
67 struct sctp_sendv_spa& GetInfo() const { return *mInfo; };
68 size_t GetLength() const { return mData.Length(); };
69 Span<const uint8_t> GetRemainingData() const { return mData.From(mPos); }
71 protected:
72 const Span<const uint8_t> mData;
73 struct sctp_sendv_spa* const mInfo;
74 size_t mPos = 0;
77 // For queuing outgoing messages
78 // This class copies data of an outgoing message.
79 class BufferedOutgoingMsg : public OutgoingMsg {
80 public:
81 static UniquePtr<BufferedOutgoingMsg> CopyFrom(const OutgoingMsg& msg);
83 private:
84 BufferedOutgoingMsg(nsTArray<uint8_t>&& data,
85 UniquePtr<struct sctp_sendv_spa>&& info);
86 const nsTArray<uint8_t> mDataStorage;
87 const UniquePtr<struct sctp_sendv_spa> mInfoStorage;
90 // for queuing incoming data messages before the Open or
91 // external negotiation is indicated to us
92 class QueuedDataMessage {
93 public:
94 QueuedDataMessage(uint16_t stream, uint32_t ppid, int flags,
95 const uint8_t* data, uint32_t length)
96 : mStream(stream), mPpid(ppid), mFlags(flags), mData(data, length) {}
98 const uint16_t mStream;
99 const uint32_t mPpid;
100 const int mFlags;
101 const nsTArray<uint8_t> mData;
104 // One per PeerConnection
105 class DataChannelConnection final : public net::NeckoTargetHolder,
106 public sigslot::has_slots<> {
107 friend class DataChannel;
108 friend class DataChannelOnMessageAvailable;
109 friend class DataChannelConnectRunnable;
111 virtual ~DataChannelConnection();
113 public:
114 enum class PendingType {
115 None, // No outgoing messages are pending.
116 Dcep, // Outgoing DCEP messages are pending.
117 Data, // Outgoing data channel messages are pending.
120 class DataConnectionListener : public SupportsWeakPtr {
121 public:
122 virtual ~DataConnectionListener() = default;
124 // Called when a new DataChannel has been opened by the other side.
125 virtual void NotifyDataChannel(already_AddRefed<DataChannel> channel) = 0;
127 // Called when a DataChannel transitions to state open
128 virtual void NotifyDataChannelOpen(DataChannel* aChannel) = 0;
130 // Called when a DataChannel (that was open at some point in the past)
131 // transitions to state closed
132 virtual void NotifyDataChannelClosed(DataChannel* aChannel) = 0;
134 // Called when SCTP connects
135 virtual void NotifySctpConnected() = 0;
137 // Called when SCTP closes
138 virtual void NotifySctpClosed() = 0;
141 // Create a new DataChannel Connection
142 // Must be called on Main thread
143 static Maybe<RefPtr<DataChannelConnection>> Create(
144 DataConnectionListener* aListener, nsISerialEventTarget* aTarget,
145 MediaTransportHandler* aHandler, const uint16_t aLocalPort,
146 const uint16_t aNumStreams, const Maybe<uint64_t>& aMaxMessageSize);
148 DataChannelConnection(const DataChannelConnection&) = delete;
149 DataChannelConnection(DataChannelConnection&&) = delete;
150 DataChannelConnection& operator=(const DataChannelConnection&) = delete;
151 DataChannelConnection& operator=(DataChannelConnection&&) = delete;
153 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DataChannelConnection)
155 void Destroy(); // So we can spawn refs tied to runnables in shutdown
156 // Finish Destroy on STS to avoid SCTP race condition with ABORT from far end
157 void DestroyOnSTS(struct socket* aMasterSocket, struct socket* aSocket);
158 void DestroyOnSTSFinal();
160 void SetMaxMessageSize(bool aMaxMessageSizeSet, uint64_t aMaxMessageSize);
161 uint64_t GetMaxMessageSize();
163 void AppendStatsToReport(const UniquePtr<dom::RTCStatsCollection>& aReport,
164 const DOMHighResTimeStamp aTimestamp) const;
166 bool ConnectToTransport(const std::string& aTransportId, const bool aClient,
167 const uint16_t aLocalPort,
168 const uint16_t aRemotePort);
169 void TransportStateChange(const std::string& aTransportId,
170 TransportLayer::State aState);
171 void CompleteConnect();
172 void SetSignals(const std::string& aTransportId);
174 [[nodiscard]] already_AddRefed<DataChannel> Open(
175 const nsACString& label, const nsACString& protocol,
176 DataChannelReliabilityPolicy prPolicy, bool inOrder, uint32_t prValue,
177 DataChannelListener* aListener, nsISupports* aContext,
178 bool aExternalNegotiated, uint16_t aStream);
180 void Stop();
181 void Close(DataChannel* aChannel);
182 void CloseLocked(DataChannel* aChannel) MOZ_REQUIRES(mLock);
183 void CloseAll();
185 // Returns a POSIX error code.
186 int SendMsg(uint16_t stream, const nsACString& aMsg) {
187 return SendDataMsgCommon(stream, aMsg, false);
190 // Returns a POSIX error code.
191 int SendBinaryMsg(uint16_t stream, const nsACString& aMsg) {
192 return SendDataMsgCommon(stream, aMsg, true);
195 // Returns a POSIX error code.
196 int SendBlob(uint16_t stream, nsIInputStream* aBlob);
198 // Called on data reception from the SCTP library
199 // must(?) be public so my c->c++ trampoline can call it
200 // May be called with (STS thread) or without the lock
201 int ReceiveCallback(struct socket* sock, void* data, size_t datalen,
202 struct sctp_rcvinfo rcv, int flags);
204 void ReadBlob(already_AddRefed<DataChannelConnection> aThis, uint16_t aStream,
205 nsIInputStream* aBlob);
207 bool SendDeferredMessages() MOZ_REQUIRES(mLock);
209 int SctpDtlsOutput(void* addr, void* buffer, size_t length, uint8_t tos,
210 uint8_t set_df);
212 bool InShutdown() const {
213 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
214 return mShutdown;
215 #else
216 return false;
217 #endif
220 private:
221 class Channels {
222 public:
223 using ChannelArray = AutoTArray<RefPtr<DataChannel>, 16>;
225 Channels() : mMutex("DataChannelConnection::Channels::mMutex") {}
226 Channels(const Channels&) = delete;
227 Channels(Channels&&) = delete;
228 Channels& operator=(const Channels&) = delete;
229 Channels& operator=(Channels&&) = delete;
231 void Insert(const RefPtr<DataChannel>& aChannel);
232 bool Remove(const RefPtr<DataChannel>& aChannel);
233 RefPtr<DataChannel> Get(uint16_t aId) const;
234 ChannelArray GetAll() const {
235 MutexAutoLock lock(mMutex);
236 return mChannels.Clone();
238 RefPtr<DataChannel> GetNextChannel(uint16_t aCurrentId) const;
240 private:
241 struct IdComparator {
242 bool Equals(const RefPtr<DataChannel>& aChannel, uint16_t aId) const;
243 bool LessThan(const RefPtr<DataChannel>& aChannel, uint16_t aId) const;
244 bool Equals(const RefPtr<DataChannel>& a1,
245 const RefPtr<DataChannel>& a2) const;
246 bool LessThan(const RefPtr<DataChannel>& a1,
247 const RefPtr<DataChannel>& a2) const;
249 mutable Mutex mMutex;
250 ChannelArray mChannels MOZ_GUARDED_BY(mMutex);
253 DataChannelConnection(DataConnectionListener* aListener,
254 nsISerialEventTarget* aTarget,
255 MediaTransportHandler* aHandler);
257 bool Init(const uint16_t aLocalPort, const uint16_t aNumStreams,
258 const Maybe<uint64_t>& aMaxMessageSize);
260 DataChannelConnectionState GetState() const MOZ_REQUIRES(mLock) {
261 mLock.AssertCurrentThreadOwns();
263 return mState;
266 void SetState(DataChannelConnectionState aState) MOZ_REQUIRES(mLock);
267 static int OnThresholdEvent(struct socket* sock, uint32_t sb_free,
268 void* ulp_info);
270 static void DTLSConnectThread(void* data);
271 void SendPacket(std::unique_ptr<MediaPacket>&& packet);
272 void SctpDtlsInput(const std::string& aTransportId,
273 const MediaPacket& packet);
274 DataChannel* FindChannelByStream(uint16_t stream) MOZ_REQUIRES(mLock);
275 uint16_t FindFreeStream() const MOZ_REQUIRES(mLock);
276 bool RequestMoreStreams(int32_t aNeeded = 16) MOZ_REQUIRES(mLock);
277 uint32_t UpdateCurrentStreamIndex() MOZ_REQUIRES(mLock);
278 uint32_t GetCurrentStreamIndex() MOZ_REQUIRES(mLock);
279 int SendControlMessage(const uint8_t* data, uint32_t len, uint16_t stream)
280 MOZ_REQUIRES(mLock);
281 int SendOpenAckMessage(uint16_t stream) MOZ_REQUIRES(mLock);
282 int SendOpenRequestMessage(const nsACString& label,
283 const nsACString& protocol, uint16_t stream,
284 bool unordered,
285 DataChannelReliabilityPolicy prPolicy,
286 uint32_t prValue) MOZ_REQUIRES(mLock);
287 bool SendBufferedMessages(nsTArray<UniquePtr<BufferedOutgoingMsg>>& buffer,
288 size_t* aWritten) MOZ_REQUIRES(mLock);
289 int SendMsgInternal(OutgoingMsg& msg, size_t* aWritten) MOZ_REQUIRES(mLock);
290 int SendMsgInternalOrBuffer(nsTArray<UniquePtr<BufferedOutgoingMsg>>& buffer,
291 OutgoingMsg& msg, bool& buffered,
292 size_t* aWritten) MOZ_REQUIRES(mLock);
293 int SendDataMsgInternalOrBuffer(DataChannel& channel, const uint8_t* data,
294 size_t len, uint32_t ppid)
295 MOZ_REQUIRES(mLock);
296 int SendDataMsg(DataChannel& channel, const uint8_t* data, size_t len,
297 uint32_t ppidPartial, uint32_t ppidFinal) MOZ_REQUIRES(mLock);
298 int SendDataMsgCommon(uint16_t stream, const nsACString& aMsg, bool isBinary);
300 void DeliverQueuedData(uint16_t stream) MOZ_REQUIRES(mLock);
302 already_AddRefed<DataChannel> OpenFinish(
303 already_AddRefed<DataChannel>&& aChannel) MOZ_REQUIRES(mLock);
305 void ProcessQueuedOpens() MOZ_REQUIRES(mLock);
306 void ClearResets() MOZ_REQUIRES(mLock);
307 void SendOutgoingStreamReset() MOZ_REQUIRES(mLock);
308 void ResetOutgoingStream(DataChannel& aChannel) MOZ_REQUIRES(mLock);
309 void HandleOpenRequestMessage(
310 const struct rtcweb_datachannel_open_request* req, uint32_t length,
311 uint16_t stream) MOZ_REQUIRES(mLock);
312 void HandleOpenAckMessage(const struct rtcweb_datachannel_ack* ack,
313 uint32_t length, uint16_t stream);
314 void HandleUnknownMessage(uint32_t ppid, uint32_t length, uint16_t stream)
315 MOZ_REQUIRES(mLock);
316 uint8_t BufferMessage(nsACString& recvBuffer, const void* data,
317 uint32_t length, uint32_t ppid, int flags);
318 void HandleDataMessage(const void* data, size_t length, uint32_t ppid,
319 uint16_t stream, int flags) MOZ_REQUIRES(mLock);
320 void HandleDCEPMessage(const void* buffer, size_t length, uint32_t ppid,
321 uint16_t stream, int flags) MOZ_REQUIRES(mLock);
322 void HandleMessage(const void* buffer, size_t length, uint32_t ppid,
323 uint16_t stream, int flags) MOZ_REQUIRES(mLock);
324 void HandleAssociationChangeEvent(const struct sctp_assoc_change* sac)
325 MOZ_REQUIRES(mLock);
326 void HandlePeerAddressChangeEvent(const struct sctp_paddr_change* spc)
327 MOZ_REQUIRES(mLock);
328 void HandleRemoteErrorEvent(const struct sctp_remote_error* sre)
329 MOZ_REQUIRES(mLock);
330 void HandleShutdownEvent(const struct sctp_shutdown_event* sse)
331 MOZ_REQUIRES(mLock);
332 void HandleAdaptationIndication(const struct sctp_adaptation_event* sai)
333 MOZ_REQUIRES(mLock);
334 void HandlePartialDeliveryEvent(const struct sctp_pdapi_event* spde)
335 MOZ_REQUIRES(mLock);
336 void HandleSendFailedEvent(const struct sctp_send_failed_event* ssfe)
337 MOZ_REQUIRES(mLock);
338 void HandleStreamResetEvent(const struct sctp_stream_reset_event* strrst)
339 MOZ_REQUIRES(mLock);
340 void HandleStreamChangeEvent(const struct sctp_stream_change_event* strchg)
341 MOZ_REQUIRES(mLock);
342 void HandleNotification(const union sctp_notification* notif, size_t n)
343 MOZ_REQUIRES(mLock);
345 bool IsSTSThread() const {
346 bool on = false;
347 if (mSTS) {
348 mSTS->IsOnCurrentThread(&on);
350 return on;
353 mutable Mutex mLock;
354 // Avoid cycles with PeerConnectionImpl
355 // Use from main thread only as WeakPtr is not threadsafe
356 WeakPtr<DataConnectionListener> mListener;
357 bool mSendInterleaved MOZ_GUARDED_BY(mLock) = false;
358 // MainThread only
359 bool mMaxMessageSizeSet = false;
360 // mMaxMessageSize is only set on MainThread, but read off-main-thread
361 uint64_t mMaxMessageSize MOZ_GUARDED_BY(mLock) = 0;
362 // Main thread only
363 Maybe<bool> mAllocateEven;
364 // Data:
365 // NOTE: while this container will auto-expand, increases in the number of
366 // channels available from the stack must be negotiated!
367 // Accessed from both main and sts, API is threadsafe
368 Channels mChannels;
369 // STS only
370 uint32_t mCurrentStream = 0;
371 // STS and main
372 std::set<RefPtr<DataChannel>> mPending MOZ_GUARDED_BY(mLock);
373 size_t mNegotiatedIdLimit MOZ_GUARDED_BY(mLock) = 0;
374 PendingType mPendingType MOZ_GUARDED_BY(mLock) = PendingType::None;
375 // holds data that's come in before a channel is open
376 nsTArray<UniquePtr<QueuedDataMessage>> mQueuedData MOZ_GUARDED_BY(mLock);
377 // holds outgoing control messages
378 nsTArray<UniquePtr<BufferedOutgoingMsg>> mBufferedControl
379 MOZ_GUARDED_BY(mLock);
381 // Streams pending reset. Accessed from main and STS.
382 AutoTArray<uint16_t, 4> mStreamsResetting MOZ_GUARDED_BY(mLock);
383 // accessed from STS thread
384 struct socket* mMasterSocket = nullptr;
385 // cloned from mMasterSocket on successful Connect on STS thread
386 struct socket* mSocket = nullptr;
387 DataChannelConnectionState mState MOZ_GUARDED_BY(mLock) =
388 DataChannelConnectionState::Closed;
390 std::string mTransportId;
391 bool mConnectedToTransportHandler = false;
392 RefPtr<MediaTransportHandler> mTransportHandler;
393 nsCOMPtr<nsIEventTarget> mSTS;
394 uint16_t mLocalPort = 0; // Accessed from connect thread
395 uint16_t mRemotePort = 0;
397 nsCOMPtr<nsIThread> mInternalIOThread = nullptr;
398 nsCString mRecvBuffer;
400 // Workaround to prevent a message from being received on main before the
401 // sender sees the decrease in bufferedAmount.
402 bool mDeferSend = false;
403 std::vector<std::unique_ptr<MediaPacket>> mDeferredSend;
405 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
406 bool mShutdown;
407 #endif
408 uintptr_t mId = 0;
411 class DataChannel {
412 friend class DataChannelOnMessageAvailable;
413 friend class DataChannelConnection;
415 public:
416 struct TrafficCounters {
417 uint32_t mMessagesSent = 0;
418 uint64_t mBytesSent = 0;
419 uint32_t mMessagesReceived = 0;
420 uint64_t mBytesReceived = 0;
423 DataChannel(DataChannelConnection* connection, uint16_t stream,
424 DataChannelState state, const nsACString& label,
425 const nsACString& protocol, DataChannelReliabilityPolicy policy,
426 uint32_t value, bool ordered, bool negotiated,
427 DataChannelListener* aListener, nsISupports* aContext);
428 DataChannel(const DataChannel&) = delete;
429 DataChannel(DataChannel&&) = delete;
430 DataChannel& operator=(const DataChannel&) = delete;
431 DataChannel& operator=(DataChannel&&) = delete;
433 private:
434 ~DataChannel();
436 public:
437 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DataChannel)
439 // when we disconnect from the connection after stream RESET
440 void StreamClosedLocked();
442 // Complete dropping of the link between DataChannel and the connection.
443 // After this, except for a few methods below listed to be safe, you can't
444 // call into DataChannel.
445 void ReleaseConnection();
447 // Close this DataChannel. Can be called multiple times. MUST be called
448 // before destroying the DataChannel (state must be CLOSED or CLOSING).
449 void Close();
451 // Set the listener (especially for channels created from the other side)
452 void SetListener(DataChannelListener* aListener, nsISupports* aContext);
454 // Helper for send methods that converts POSIX error codes to an ErrorResult.
455 static void SendErrnoToErrorResult(int error, size_t aMessageSize,
456 ErrorResult& aRv);
458 // Send a string
459 void SendMsg(const nsACString& aMsg, ErrorResult& aRv);
461 // Send a binary message (TypedArray)
462 void SendBinaryMsg(const nsACString& aMsg, ErrorResult& aRv);
464 // Send a binary blob
465 void SendBinaryBlob(dom::Blob& aBlob, ErrorResult& aRv);
467 DataChannelReliabilityPolicy GetType() const { return mPrPolicy; }
469 dom::Nullable<uint16_t> GetMaxPacketLifeTime() const;
471 dom::Nullable<uint16_t> GetMaxRetransmits() const;
473 bool GetNegotiated() const { return mNegotiated; }
475 bool GetOrdered() const { return mOrdered; }
477 void IncrementBufferedAmount(uint32_t aSize, ErrorResult& aRv);
478 void DecrementBufferedAmount(uint32_t aSize);
480 // Amount of data buffered to send
481 uint32_t GetBufferedAmount() const {
482 MOZ_ASSERT(NS_IsMainThread());
483 return mBufferedAmount;
486 // Trigger amount for generating BufferedAmountLow events
487 uint32_t GetBufferedAmountLowThreshold() const;
488 void SetBufferedAmountLowThreshold(uint32_t aThreshold);
490 void AnnounceOpen();
491 // TODO(bug 843625): Optionally pass an error here.
492 void AnnounceClosed();
494 // Find out state
495 DataChannelState GetReadyState() const {
496 MOZ_ASSERT(NS_IsMainThread());
497 return mReadyState;
500 // Set ready state
501 void SetReadyState(DataChannelState aState);
503 void GetLabel(nsAString& aLabel) { CopyUTF8toUTF16(mLabel, aLabel); }
504 void GetProtocol(nsAString& aProtocol) {
505 CopyUTF8toUTF16(mProtocol, aProtocol);
507 uint16_t GetStream() const { return mStream; }
509 void SendOrQueue(DataChannelOnMessageAvailable* aMessage)
510 MOZ_REQUIRES(mConnection->mLock);
512 TrafficCounters GetTrafficCounters() const;
514 bool HasSentStreamReset() const { return mHasSentStreamReset; }
515 void SetHasSentStreamReset() { mHasSentStreamReset = true; }
517 private:
518 nsresult AddDataToBinaryMsg(const char* data, uint32_t size);
519 bool EnsureValidStream(ErrorResult& aRv);
520 void WithTrafficCounters(const std::function<void(TrafficCounters&)>&);
522 // These are both mainthread only
523 DataChannelListener* mListener;
524 nsCOMPtr<nsISupports> mContext;
526 RefPtr<DataChannelConnection> mConnection;
527 // mainthread only
528 bool mEverOpened = false;
529 const nsCString mLabel;
530 const nsCString mProtocol;
531 // This is mainthread only
532 DataChannelState mReadyState;
533 uint16_t mStream;
534 const DataChannelReliabilityPolicy mPrPolicy;
535 const uint32_t mPrValue;
536 // Accessed on main and STS
537 const bool mNegotiated;
538 const bool mOrdered;
539 // The data channel has completed the open procedure and the client has been
540 // notified about it.
541 bool mHasFinishedOpen = false;
542 // The channel has been opened, but the peer has not yet acked - ensures that
543 // the messages are sent ordered until this is cleared.
544 bool mWaitingForAck = false;
545 // A too large message was attempted to be sent - closing data channel.
546 bool mClosingTooLarge = false;
547 bool mHasSentStreamReset = false;
548 bool mIsRecvBinary;
549 size_t mBufferedThreshold;
550 // Read/written on main only. Decremented via message-passing, because the
551 // spec requires us to queue a task for this.
552 size_t mBufferedAmount;
553 nsCString mRecvBuffer;
554 nsTArray<UniquePtr<BufferedOutgoingMsg>> mBufferedData
555 MOZ_GUARDED_BY(mConnection->mLock);
556 nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget;
557 mutable Mutex mStatsLock;
558 TrafficCounters mTrafficCounters MOZ_GUARDED_BY(mStatsLock);
561 // used to dispatch notifications of incoming data to the main thread
562 // Patterned on CallOnMessageAvailable in WebSockets
563 // Also used to proxy other items to MainThread
564 class DataChannelOnMessageAvailable : public Runnable {
565 public:
566 enum class EventType {
567 OnConnection,
568 OnDisconnected,
569 OnChannelCreated,
570 OnDataString,
571 OnDataBinary,
574 DataChannelOnMessageAvailable(
575 EventType aType, DataChannelConnection* aConnection,
576 DataChannel* aChannel,
577 nsCString& aData) // XXX this causes inefficiency
578 : Runnable("DataChannelOnMessageAvailable"),
579 mType(aType),
580 mChannel(aChannel),
581 mConnection(aConnection),
582 mData(aData) {}
584 DataChannelOnMessageAvailable(EventType aType, DataChannel* aChannel)
585 : Runnable("DataChannelOnMessageAvailable"),
586 mType(aType),
587 mChannel(aChannel) {}
588 // XXX is it safe to leave mData uninitialized? This should only be
589 // used for notifications that don't use them, but I'd like more
590 // bulletproof compile-time checking.
592 DataChannelOnMessageAvailable(EventType aType,
593 DataChannelConnection* aConnection,
594 DataChannel* aChannel)
595 : Runnable("DataChannelOnMessageAvailable"),
596 mType(aType),
597 mChannel(aChannel),
598 mConnection(aConnection) {}
600 // for ON_CONNECTION/ON_DISCONNECTED
601 DataChannelOnMessageAvailable(EventType aType,
602 DataChannelConnection* aConnection)
603 : Runnable("DataChannelOnMessageAvailable"),
604 mType(aType),
605 mConnection(aConnection) {}
606 DataChannelOnMessageAvailable(const DataChannelOnMessageAvailable&) = delete;
607 DataChannelOnMessageAvailable(DataChannelOnMessageAvailable&&) = delete;
608 DataChannelOnMessageAvailable& operator=(
609 const DataChannelOnMessageAvailable&) = delete;
610 DataChannelOnMessageAvailable& operator=(DataChannelOnMessageAvailable&&) =
611 delete;
613 NS_IMETHOD Run() override;
615 private:
616 ~DataChannelOnMessageAvailable() = default;
618 EventType mType;
619 // XXX should use union
620 RefPtr<DataChannel> mChannel;
621 RefPtr<DataChannelConnection> mConnection;
622 nsCString mData;
625 } // namespace mozilla
627 #endif // NETWERK_SCTP_DATACHANNEL_DATACHANNEL_H_