1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/mtransport/nr_timer.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,174 @@ 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 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.11 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.12 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.13 + 1.14 +// Original code by: ekr@rtfm.com 1.15 + 1.16 +// Implementation of the NR timer interface 1.17 + 1.18 +// Some code here copied from nrappkit. The license was. 1.19 + 1.20 +/** 1.21 + Copyright (C) 2004, Network Resonance, Inc. 1.22 + Copyright (C) 2006, Network Resonance, Inc. 1.23 + All Rights Reserved 1.24 + 1.25 + Redistribution and use in source and binary forms, with or without 1.26 + modification, are permitted provided that the following conditions 1.27 + are met: 1.28 + 1.29 + 1. Redistributions of source code must retain the above copyright 1.30 + notice, this list of conditions and the following disclaimer. 1.31 + 2. Redistributions in binary form must reproduce the above copyright 1.32 + notice, this list of conditions and the following disclaimer in the 1.33 + documentation and/or other materials provided with the distribution. 1.34 + 3. Neither the name of Network Resonance, Inc. nor the name of any 1.35 + contributors to this software may be used to endorse or promote 1.36 + products derived from this software without specific prior written 1.37 + permission. 1.38 + 1.39 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 1.40 + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.41 + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.42 + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 1.43 + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.44 + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.45 + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.46 + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.47 + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.48 + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 1.49 + POSSIBILITY OF SUCH DAMAGE. 1.50 + 1.51 + 1.52 + ekr@rtfm.com Sun Feb 22 19:35:24 2004 1.53 + */ 1.54 + 1.55 +#include <string> 1.56 + 1.57 +#include "nsCOMPtr.h" 1.58 +#include "nsComponentManagerUtils.h" 1.59 +#include "nsServiceManagerUtils.h" 1.60 +#include "nsIEventTarget.h" 1.61 +#include "nsITimer.h" 1.62 +#include "nsNetCID.h" 1.63 +#include "runnable_utils.h" 1.64 + 1.65 +extern "C" { 1.66 +#include "nr_api.h" 1.67 +#include "async_timer.h" 1.68 +} 1.69 + 1.70 + 1.71 +namespace mozilla { 1.72 + 1.73 +class nrappkitTimerCallback : public nsITimerCallback 1.74 +{ 1.75 +public: 1.76 + // We're going to release ourself in the callback, so we need to be threadsafe 1.77 + NS_DECL_THREADSAFE_ISUPPORTS 1.78 + NS_DECL_NSITIMERCALLBACK 1.79 + 1.80 + nrappkitTimerCallback(NR_async_cb cb, void *cb_arg, 1.81 + const char *function, int line) 1.82 + : cb_(cb), cb_arg_(cb_arg), function_(function), line_(line) { 1.83 + } 1.84 + 1.85 +private: 1.86 + virtual ~nrappkitTimerCallback() {} 1.87 + 1.88 +protected: 1.89 + /* additional members */ 1.90 + NR_async_cb cb_; 1.91 + void *cb_arg_; 1.92 + std::string function_; 1.93 + int line_; 1.94 +}; 1.95 + 1.96 +NS_IMPL_ISUPPORTS(nrappkitTimerCallback, nsITimerCallback) 1.97 + 1.98 +NS_IMETHODIMP nrappkitTimerCallback::Notify(nsITimer *timer) { 1.99 + r_log(LOG_GENERIC, LOG_DEBUG, "Timer callback fired (set in %s:%d)", 1.100 + function_.c_str(), line_); 1.101 + 1.102 + cb_(0, 0, cb_arg_); 1.103 + 1.104 + // Allow the timer to go away. 1.105 + timer->Release(); 1.106 + return NS_OK; 1.107 +} 1.108 +} // close namespace 1.109 + 1.110 + 1.111 +using namespace mozilla; 1.112 + 1.113 +// These timers must only be used from the STS thread. 1.114 +// This function is a helper that enforces that. 1.115 +static void CheckSTSThread() { 1.116 + nsresult rv; 1.117 + 1.118 + nsCOMPtr<nsIEventTarget> sts_thread; 1.119 + 1.120 + sts_thread = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); 1.121 + 1.122 + MOZ_ASSERT(NS_SUCCEEDED(rv)); 1.123 + ASSERT_ON_THREAD(sts_thread); 1.124 +} 1.125 + 1.126 +int NR_async_timer_set(int timeout, NR_async_cb cb, void *arg, char *func, 1.127 + int l, void **handle) { 1.128 + nsresult rv; 1.129 + CheckSTSThread(); 1.130 + 1.131 + nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv); 1.132 + if (NS_FAILED(rv)) { 1.133 + return(R_FAILED); 1.134 + } 1.135 + 1.136 + rv = timer->InitWithCallback(new nrappkitTimerCallback(cb, arg, func, l), 1.137 + timeout, nsITimer::TYPE_ONE_SHOT); 1.138 + if (NS_FAILED(rv)) { 1.139 + return R_FAILED; 1.140 + } 1.141 + 1.142 + // We need an AddRef here to keep the timer alive, per the spec. 1.143 + timer->AddRef(); 1.144 + 1.145 + if (handle) 1.146 + *handle = timer.get(); 1.147 + // Bug 818806: if we have no handle to the timer, we have no way to avoid 1.148 + // it leaking (though not the callback object) if it never fires (or if 1.149 + // we exit before it fires). 1.150 + 1.151 + return 0; 1.152 +} 1.153 + 1.154 +int NR_async_schedule(NR_async_cb cb, void *arg, char *func, int l) { 1.155 + // No need to check the thread because we check it next in the 1.156 + // timer set. 1.157 + return NR_async_timer_set(0, cb, arg, func, l, nullptr); 1.158 +} 1.159 + 1.160 +int NR_async_timer_cancel(void *handle) { 1.161 + // Check for the handle being nonzero because sometimes we get 1.162 + // no-op cancels that aren't on the STS thread. This can be 1.163 + // non-racy as long as the upper-level code is careful. 1.164 + if (!handle) 1.165 + return 0; 1.166 + 1.167 + CheckSTSThread(); 1.168 + 1.169 + nsITimer *timer = static_cast<nsITimer *>(handle); 1.170 + 1.171 + timer->Cancel(); 1.172 + // Allow the timer to go away. 1.173 + timer->Release(); 1.174 + 1.175 + return 0; 1.176 +} 1.177 +