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 // Original author: ekr@rtfm.com
14 #include "nsIComponentManager.h"
15 #include "nsComponentManagerUtils.h"
16 #include "nsIComponentRegistrar.h"
17 #include "nsIEventTarget.h"
18 #include "nsIIOService.h"
19 #include "nsIServiceManager.h"
20 #include "nsISocketTransportService.h"
21 #include "nsServiceManagerUtils.h"
23 #include "transportflow.h"
24 #include "transportlayerloopback.h"
28 MOZ_MTLOG_MODULE("mtransport")
30 nsresult
TransportLayerLoopback::Init() {
31 timer_
= do_CreateInstance(NS_TIMER_CONTRACTID
);
34 return NS_ERROR_FAILURE
;
37 target_
= do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID
, &rv
);
38 MOZ_ASSERT(NS_SUCCEEDED(rv
));
39 if (!NS_SUCCEEDED(rv
))
42 timer_
->SetTarget(target_
);
44 packets_lock_
= PR_NewLock();
45 MOZ_ASSERT(packets_lock_
);
47 return NS_ERROR_FAILURE
;
49 deliverer_
= new Deliverer(this);
51 timer_
->InitWithCallback(deliverer_
, 100, nsITimer::TYPE_REPEATING_SLACK
);
56 // Connect to the other side
57 void TransportLayerLoopback::Connect(TransportLayerLoopback
* peer
) {
60 TL_SET_STATE(TS_OPEN
);
64 TransportLayerLoopback::SendPacket(const unsigned char *data
, size_t len
) {
65 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "SendPacket(" << len
<< ")");
68 MOZ_MTLOG(ML_ERROR
, "Discarding packet because peer not attached");
72 nsresult res
= peer_
->QueuePacket(data
, len
);
73 if (!NS_SUCCEEDED(res
))
76 return static_cast<TransportResult
>(len
);
79 nsresult
TransportLayerLoopback::QueuePacket(const unsigned char *data
,
81 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< " Enqueuing packet of length " << len
);
82 MOZ_ASSERT(packets_lock_
);
84 PR_Lock(packets_lock_
);
86 packets_
.push(new QueuedPacket());
87 packets_
.back()->Assign(data
, len
);
89 PRStatus r
= PR_Unlock(packets_lock_
);
90 MOZ_ASSERT(r
== PR_SUCCESS
);
92 return NS_ERROR_FAILURE
;
98 void TransportLayerLoopback::DeliverPackets() {
99 while (!packets_
.empty()) {
100 QueuedPacket
*packet
= packets_
.front();
103 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< " Delivering packet of length " <<
105 SignalPacketReceived(this, packet
->data(), packet
->len());
111 NS_IMPL_ISUPPORTS(TransportLayerLoopback::Deliverer
, nsITimerCallback
)
113 NS_IMETHODIMP
TransportLayerLoopback::Deliverer::Notify(nsITimer
*timer
) {
117 layer_
->DeliverPackets();