Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/media/mtransport/transportlayerloopback.cpp
Line
Count
Source (jump to first uncovered line)
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/. */
6
7
// Original author: ekr@rtfm.com
8
9
#include "logging.h"
10
#include "nspr.h"
11
#include "prlock.h"
12
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"
22
#include "nsString.h"
23
24
#include "transportflow.h"
25
#include "transportlayerloopback.h"
26
27
namespace mozilla {
28
29
MOZ_MTLOG_MODULE("mtransport")
30
31
0
nsresult TransportLayerLoopback::Init() {
32
0
  nsresult rv;
33
0
  target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
34
0
  MOZ_ASSERT(NS_SUCCEEDED(rv));
35
0
  if (!NS_SUCCEEDED(rv))
36
0
    return rv;
37
0
38
0
  timer_ = NS_NewTimer(target_);
39
0
  MOZ_ASSERT(timer_);
40
0
  if (!timer_)
41
0
    return NS_ERROR_FAILURE;
42
0
43
0
  packets_lock_ = PR_NewLock();
44
0
  MOZ_ASSERT(packets_lock_);
45
0
  if (!packets_lock_)
46
0
    return NS_ERROR_FAILURE;
47
0
48
0
  deliverer_ = new Deliverer(this);
49
0
50
0
  timer_->InitWithCallback(deliverer_, 100, nsITimer::TYPE_REPEATING_SLACK);
51
0
52
0
  return NS_OK;
53
0
}
54
55
// Connect to the other side
56
0
void TransportLayerLoopback::Connect(TransportLayerLoopback* peer) {
57
0
  peer_ = peer;
58
0
59
0
  TL_SET_STATE(TS_OPEN);
60
0
}
61
62
TransportResult
63
0
TransportLayerLoopback::SendPacket(MediaPacket& packet) {
64
0
  MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "SendPacket(" << packet.len() << ")");
65
0
66
0
  if (!peer_) {
67
0
    MOZ_MTLOG(ML_ERROR, "Discarding packet because peer not attached");
68
0
    return TE_ERROR;
69
0
  }
70
0
71
0
  size_t len = packet.len();
72
0
  nsresult res = peer_->QueuePacket(packet);
73
0
  if (!NS_SUCCEEDED(res))
74
0
    return TE_ERROR;
75
0
76
0
  return static_cast<TransportResult>(len);
77
0
}
78
79
0
nsresult TransportLayerLoopback::QueuePacket(MediaPacket& packet) {
80
0
  MOZ_ASSERT(packets_lock_);
81
0
82
0
  PR_Lock(packets_lock_);
83
0
84
0
  if (combinePackets_ && !packets_.empty()) {
85
0
    MediaPacket *prevPacket = packets_.front();
86
0
87
0
    MOZ_MTLOG(ML_DEBUG, LAYER_INFO << " Enqueuing combined packets of length " << prevPacket->len() << " and " << packet.len());
88
0
    auto combined = MakeUnique<uint8_t[]>(prevPacket->len() + packet.len());
89
0
    memcpy(combined.get(), prevPacket->data(), prevPacket->len());
90
0
    memcpy(combined.get() + prevPacket->len(), packet.data(), packet.len());
91
0
    prevPacket->Take(std::move(combined), prevPacket->len() + packet.len());
92
0
  } else {
93
0
    MOZ_MTLOG(ML_DEBUG, LAYER_INFO << " Enqueuing packet of length " << packet.len());
94
0
    packets_.push(new MediaPacket(std::move(packet)));
95
0
  }
96
0
97
0
  PRStatus r = PR_Unlock(packets_lock_);
98
0
  MOZ_ASSERT(r == PR_SUCCESS);
99
0
  if (r != PR_SUCCESS)
100
0
    return NS_ERROR_FAILURE;
101
0
102
0
  return NS_OK;
103
0
}
104
105
106
0
void TransportLayerLoopback::DeliverPackets() {
107
0
  while (!packets_.empty()) {
108
0
    UniquePtr<MediaPacket> packet(packets_.front());
109
0
    packets_.pop();
110
0
111
0
    MOZ_MTLOG(ML_DEBUG, LAYER_INFO << " Delivering packet of length " <<
112
0
         packet->len());
113
0
    SignalPacketReceived(this, *packet);
114
0
  }
115
0
}
116
117
NS_IMPL_ISUPPORTS(TransportLayerLoopback::Deliverer, nsITimerCallback, nsINamed)
118
119
0
NS_IMETHODIMP TransportLayerLoopback::Deliverer::Notify(nsITimer *timer) {
120
0
  if (!layer_)
121
0
    return NS_OK;
122
0
123
0
  layer_->DeliverPackets();
124
0
125
0
  return NS_OK;
126
0
}
127
128
0
NS_IMETHODIMP TransportLayerLoopback::Deliverer::GetName(nsACString& aName) {
129
0
  aName.AssignLiteral("TransportLayerLoopback::Deliverer");
130
0
  return NS_OK;
131
0
}
132
133
}  // close namespace