Bumping gaia.json for 2 gaia revision(s) a=gaia-bump
[gecko.git] / media / mtransport / transportlayerloopback.cpp
bloba1a3d2ccdc6c7d29e17aab2901089a6e1df23fca
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
9 #include "logging.h"
10 #include "nspr.h"
11 #include "prlock.h"
13 #include "nsNetCID.h"
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"
26 namespace mozilla {
28 MOZ_MTLOG_MODULE("mtransport")
30 nsresult TransportLayerLoopback::Init() {
31 timer_ = do_CreateInstance(NS_TIMER_CONTRACTID);
32 MOZ_ASSERT(timer_);
33 if (!timer_)
34 return NS_ERROR_FAILURE;
36 nsresult rv;
37 target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
38 MOZ_ASSERT(NS_SUCCEEDED(rv));
39 if (!NS_SUCCEEDED(rv))
40 return rv;
42 timer_->SetTarget(target_);
44 packets_lock_ = PR_NewLock();
45 MOZ_ASSERT(packets_lock_);
46 if (!packets_lock_)
47 return NS_ERROR_FAILURE;
49 deliverer_ = new Deliverer(this);
51 timer_->InitWithCallback(deliverer_, 100, nsITimer::TYPE_REPEATING_SLACK);
53 return NS_OK;
56 // Connect to the other side
57 void TransportLayerLoopback::Connect(TransportLayerLoopback* peer) {
58 peer_ = peer;
60 TL_SET_STATE(TS_OPEN);
63 TransportResult
64 TransportLayerLoopback::SendPacket(const unsigned char *data, size_t len) {
65 MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "SendPacket(" << len << ")");
67 if (!peer_) {
68 MOZ_MTLOG(ML_ERROR, "Discarding packet because peer not attached");
69 return TE_ERROR;
72 nsresult res = peer_->QueuePacket(data, len);
73 if (!NS_SUCCEEDED(res))
74 return TE_ERROR;
76 return static_cast<TransportResult>(len);
79 nsresult TransportLayerLoopback::QueuePacket(const unsigned char *data,
80 size_t len) {
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);
91 if (r != PR_SUCCESS)
92 return NS_ERROR_FAILURE;
94 return NS_OK;
98 void TransportLayerLoopback::DeliverPackets() {
99 while (!packets_.empty()) {
100 QueuedPacket *packet = packets_.front();
101 packets_.pop();
103 MOZ_MTLOG(ML_DEBUG, LAYER_INFO << " Delivering packet of length " <<
104 packet->len());
105 SignalPacketReceived(this, packet->data(), packet->len());
107 delete packet;
111 NS_IMPL_ISUPPORTS(TransportLayerLoopback::Deliverer, nsITimerCallback)
113 NS_IMETHODIMP TransportLayerLoopback::Deliverer::Notify(nsITimer *timer) {
114 if (!layer_)
115 return NS_OK;
117 layer_->DeliverPackets();
119 return NS_OK;
121 } // close namespace