media/mtransport/transportlayerloopback.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/mtransport/transportlayerloopback.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,121 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=2 et sw=2 tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +// Original author: ekr@rtfm.com
    1.11 +
    1.12 +#include "logging.h"
    1.13 +#include "nspr.h"
    1.14 +#include "prlock.h"
    1.15 +
    1.16 +#include "nsNetCID.h"
    1.17 +#include "nsIComponentManager.h"
    1.18 +#include "nsComponentManagerUtils.h"
    1.19 +#include "nsIComponentRegistrar.h"
    1.20 +#include "nsIEventTarget.h"
    1.21 +#include "nsIIOService.h"
    1.22 +#include "nsIServiceManager.h"
    1.23 +#include "nsISocketTransportService.h"
    1.24 +#include "nsServiceManagerUtils.h"
    1.25 +
    1.26 +#include "transportflow.h"
    1.27 +#include "transportlayerloopback.h"
    1.28 +
    1.29 +namespace mozilla {
    1.30 +
    1.31 +MOZ_MTLOG_MODULE("mtransport")
    1.32 +
    1.33 +nsresult TransportLayerLoopback::Init() {
    1.34 +  timer_ = do_CreateInstance(NS_TIMER_CONTRACTID);
    1.35 +  MOZ_ASSERT(timer_);
    1.36 +  if (!timer_)
    1.37 +    return NS_ERROR_FAILURE;
    1.38 +
    1.39 +  nsresult rv;
    1.40 +  target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
    1.41 +  MOZ_ASSERT(NS_SUCCEEDED(rv));
    1.42 +  if (!NS_SUCCEEDED(rv))
    1.43 +    return rv;
    1.44 +
    1.45 +  timer_->SetTarget(target_);
    1.46 +
    1.47 +  packets_lock_ = PR_NewLock();
    1.48 +  MOZ_ASSERT(packets_lock_);
    1.49 +  if (!packets_lock_)
    1.50 +    return NS_ERROR_FAILURE;
    1.51 +
    1.52 +  deliverer_ = new Deliverer(this);
    1.53 +
    1.54 +  timer_->InitWithCallback(deliverer_, 100, nsITimer::TYPE_REPEATING_SLACK);
    1.55 +
    1.56 +  return NS_OK;
    1.57 +}
    1.58 +
    1.59 +// Connect to the other side
    1.60 +void TransportLayerLoopback::Connect(TransportLayerLoopback* peer) {
    1.61 +  peer_ = peer;
    1.62 +
    1.63 +  TL_SET_STATE(TS_OPEN);
    1.64 +}
    1.65 +
    1.66 +TransportResult
    1.67 +TransportLayerLoopback::SendPacket(const unsigned char *data, size_t len) {
    1.68 +  MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "SendPacket(" << len << ")");
    1.69 +
    1.70 +  if (!peer_) {
    1.71 +    MOZ_MTLOG(ML_ERROR, "Discarding packet because peer not attached");
    1.72 +    return TE_ERROR;
    1.73 +  }
    1.74 +
    1.75 +  nsresult res = peer_->QueuePacket(data, len);
    1.76 +  if (!NS_SUCCEEDED(res))
    1.77 +    return TE_ERROR;
    1.78 +
    1.79 +  return static_cast<TransportResult>(len);
    1.80 +}
    1.81 +
    1.82 +nsresult TransportLayerLoopback::QueuePacket(const unsigned char *data,
    1.83 +                                         size_t len) {
    1.84 +  MOZ_MTLOG(ML_DEBUG, LAYER_INFO << " Enqueuing packet of length " << len);
    1.85 +  MOZ_ASSERT(packets_lock_);
    1.86 +
    1.87 +  PR_Lock(packets_lock_);
    1.88 +
    1.89 +  packets_.push(new QueuedPacket());
    1.90 +  packets_.back()->Assign(data, len);
    1.91 +
    1.92 +  PRStatus r = PR_Unlock(packets_lock_);
    1.93 +  MOZ_ASSERT(r == PR_SUCCESS);
    1.94 +  if (r != PR_SUCCESS)
    1.95 +    return NS_ERROR_FAILURE;
    1.96 +
    1.97 +  return NS_OK;
    1.98 +}
    1.99 +
   1.100 +
   1.101 +void TransportLayerLoopback::DeliverPackets() {
   1.102 +  while (!packets_.empty()) {
   1.103 +    QueuedPacket *packet = packets_.front();
   1.104 +    packets_.pop();
   1.105 +
   1.106 +    MOZ_MTLOG(ML_DEBUG, LAYER_INFO << " Delivering packet of length " <<
   1.107 +         packet->len());
   1.108 +    SignalPacketReceived(this, packet->data(), packet->len());
   1.109 +
   1.110 +    delete packet;
   1.111 +  }
   1.112 +}
   1.113 +
   1.114 +NS_IMPL_ISUPPORTS(TransportLayerLoopback::Deliverer, nsITimerCallback)
   1.115 +
   1.116 +NS_IMETHODIMP TransportLayerLoopback::Deliverer::Notify(nsITimer *timer) {
   1.117 +  if (!layer_)
   1.118 +    return NS_OK;
   1.119 +
   1.120 +  layer_->DeliverPackets();
   1.121 +
   1.122 +  return NS_OK;
   1.123 +}
   1.124 +}  // close namespace

mercurial