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