|
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 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
8 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
9 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
10 |
|
11 // Original code by: ekr@rtfm.com |
|
12 |
|
13 // Implementation of the NR timer interface |
|
14 |
|
15 // Some code here copied from nrappkit. The license was. |
|
16 |
|
17 /** |
|
18 Copyright (C) 2004, Network Resonance, Inc. |
|
19 Copyright (C) 2006, Network Resonance, Inc. |
|
20 All Rights Reserved |
|
21 |
|
22 Redistribution and use in source and binary forms, with or without |
|
23 modification, are permitted provided that the following conditions |
|
24 are met: |
|
25 |
|
26 1. Redistributions of source code must retain the above copyright |
|
27 notice, this list of conditions and the following disclaimer. |
|
28 2. Redistributions in binary form must reproduce the above copyright |
|
29 notice, this list of conditions and the following disclaimer in the |
|
30 documentation and/or other materials provided with the distribution. |
|
31 3. Neither the name of Network Resonance, Inc. nor the name of any |
|
32 contributors to this software may be used to endorse or promote |
|
33 products derived from this software without specific prior written |
|
34 permission. |
|
35 |
|
36 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' |
|
37 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
38 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
39 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
|
40 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
41 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
42 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
43 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
44 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
45 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
46 POSSIBILITY OF SUCH DAMAGE. |
|
47 |
|
48 |
|
49 ekr@rtfm.com Sun Feb 22 19:35:24 2004 |
|
50 */ |
|
51 |
|
52 #include <string> |
|
53 |
|
54 #include "nsCOMPtr.h" |
|
55 #include "nsComponentManagerUtils.h" |
|
56 #include "nsServiceManagerUtils.h" |
|
57 #include "nsIEventTarget.h" |
|
58 #include "nsITimer.h" |
|
59 #include "nsNetCID.h" |
|
60 #include "runnable_utils.h" |
|
61 |
|
62 extern "C" { |
|
63 #include "nr_api.h" |
|
64 #include "async_timer.h" |
|
65 } |
|
66 |
|
67 |
|
68 namespace mozilla { |
|
69 |
|
70 class nrappkitTimerCallback : public nsITimerCallback |
|
71 { |
|
72 public: |
|
73 // We're going to release ourself in the callback, so we need to be threadsafe |
|
74 NS_DECL_THREADSAFE_ISUPPORTS |
|
75 NS_DECL_NSITIMERCALLBACK |
|
76 |
|
77 nrappkitTimerCallback(NR_async_cb cb, void *cb_arg, |
|
78 const char *function, int line) |
|
79 : cb_(cb), cb_arg_(cb_arg), function_(function), line_(line) { |
|
80 } |
|
81 |
|
82 private: |
|
83 virtual ~nrappkitTimerCallback() {} |
|
84 |
|
85 protected: |
|
86 /* additional members */ |
|
87 NR_async_cb cb_; |
|
88 void *cb_arg_; |
|
89 std::string function_; |
|
90 int line_; |
|
91 }; |
|
92 |
|
93 NS_IMPL_ISUPPORTS(nrappkitTimerCallback, nsITimerCallback) |
|
94 |
|
95 NS_IMETHODIMP nrappkitTimerCallback::Notify(nsITimer *timer) { |
|
96 r_log(LOG_GENERIC, LOG_DEBUG, "Timer callback fired (set in %s:%d)", |
|
97 function_.c_str(), line_); |
|
98 |
|
99 cb_(0, 0, cb_arg_); |
|
100 |
|
101 // Allow the timer to go away. |
|
102 timer->Release(); |
|
103 return NS_OK; |
|
104 } |
|
105 } // close namespace |
|
106 |
|
107 |
|
108 using namespace mozilla; |
|
109 |
|
110 // These timers must only be used from the STS thread. |
|
111 // This function is a helper that enforces that. |
|
112 static void CheckSTSThread() { |
|
113 nsresult rv; |
|
114 |
|
115 nsCOMPtr<nsIEventTarget> sts_thread; |
|
116 |
|
117 sts_thread = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); |
|
118 |
|
119 MOZ_ASSERT(NS_SUCCEEDED(rv)); |
|
120 ASSERT_ON_THREAD(sts_thread); |
|
121 } |
|
122 |
|
123 int NR_async_timer_set(int timeout, NR_async_cb cb, void *arg, char *func, |
|
124 int l, void **handle) { |
|
125 nsresult rv; |
|
126 CheckSTSThread(); |
|
127 |
|
128 nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv); |
|
129 if (NS_FAILED(rv)) { |
|
130 return(R_FAILED); |
|
131 } |
|
132 |
|
133 rv = timer->InitWithCallback(new nrappkitTimerCallback(cb, arg, func, l), |
|
134 timeout, nsITimer::TYPE_ONE_SHOT); |
|
135 if (NS_FAILED(rv)) { |
|
136 return R_FAILED; |
|
137 } |
|
138 |
|
139 // We need an AddRef here to keep the timer alive, per the spec. |
|
140 timer->AddRef(); |
|
141 |
|
142 if (handle) |
|
143 *handle = timer.get(); |
|
144 // Bug 818806: if we have no handle to the timer, we have no way to avoid |
|
145 // it leaking (though not the callback object) if it never fires (or if |
|
146 // we exit before it fires). |
|
147 |
|
148 return 0; |
|
149 } |
|
150 |
|
151 int NR_async_schedule(NR_async_cb cb, void *arg, char *func, int l) { |
|
152 // No need to check the thread because we check it next in the |
|
153 // timer set. |
|
154 return NR_async_timer_set(0, cb, arg, func, l, nullptr); |
|
155 } |
|
156 |
|
157 int NR_async_timer_cancel(void *handle) { |
|
158 // Check for the handle being nonzero because sometimes we get |
|
159 // no-op cancels that aren't on the STS thread. This can be |
|
160 // non-racy as long as the upper-level code is careful. |
|
161 if (!handle) |
|
162 return 0; |
|
163 |
|
164 CheckSTSThread(); |
|
165 |
|
166 nsITimer *timer = static_cast<nsITimer *>(handle); |
|
167 |
|
168 timer->Cancel(); |
|
169 // Allow the timer to go away. |
|
170 timer->Release(); |
|
171 |
|
172 return 0; |
|
173 } |
|
174 |