|
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 #ifndef runnable_utils_h__ |
|
10 #define runnable_utils_h__ |
|
11 |
|
12 #include "nsThreadUtils.h" |
|
13 #include "mozilla/RefPtr.h" |
|
14 |
|
15 // Abstract base class for all of our templates |
|
16 namespace mozilla { |
|
17 |
|
18 class runnable_args_base : public nsRunnable { |
|
19 public: |
|
20 NS_IMETHOD Run() = 0; |
|
21 virtual bool returns_value() const { return false; } |
|
22 }; |
|
23 |
|
24 // The generated file contains four major function templates |
|
25 // (in variants for arbitrary numbers of arguments up to 10, |
|
26 // which is why it is machine generated). The four templates |
|
27 // are: |
|
28 // |
|
29 // WrapRunnable(o, m, ...) -- wraps a member function m of an object ptr o |
|
30 // WrapRunnableRet(o, m, ..., r) -- wraps a member function m of an object ptr o |
|
31 // the function returns something that can |
|
32 // be assigned to *r |
|
33 // WrapRunnableNM(f, ...) -- wraps a function f |
|
34 // WrapRunnableNMRet(f, ..., r) -- wraps a function f that returns something |
|
35 // that can be assigned to *r |
|
36 // |
|
37 // All of these template functions return a Runnable* which can be passed |
|
38 // to Dispatch(). |
|
39 #include "runnable_utils_generated.h" |
|
40 |
|
41 // Temporary hack. Really we want to have a template which will do this |
|
42 static inline nsresult RUN_ON_THREAD(nsIEventTarget *thread, nsIRunnable *runnable, uint32_t flags) { |
|
43 RefPtr<nsIRunnable> runnable_ref(runnable); |
|
44 if (thread) { |
|
45 bool on; |
|
46 nsresult rv; |
|
47 rv = thread->IsOnCurrentThread(&on); |
|
48 |
|
49 // If the target thread has already shut down, we don't want to assert. |
|
50 if (rv != NS_ERROR_NOT_INITIALIZED) { |
|
51 MOZ_ASSERT(NS_SUCCEEDED(rv)); |
|
52 } |
|
53 |
|
54 NS_ENSURE_SUCCESS(rv, rv); |
|
55 if(!on) { |
|
56 return thread->Dispatch(runnable_ref, flags); |
|
57 } |
|
58 } |
|
59 return runnable_ref->Run(); |
|
60 } |
|
61 |
|
62 static inline nsresult RUN_ON_THREAD(nsIEventTarget *thread, runnable_args_base *runnable, uint32_t flags) { |
|
63 // Detect attempts to return a value when in async mode, since this |
|
64 // most likely means someone is trying to assign to a heap variable |
|
65 // which is now out of scope. |
|
66 MOZ_ASSERT((!(runnable->returns_value()) || (flags != NS_DISPATCH_NORMAL))); |
|
67 |
|
68 return RUN_ON_THREAD(thread, static_cast<nsIRunnable *>(runnable), flags); |
|
69 } |
|
70 |
|
71 #ifdef DEBUG |
|
72 #define ASSERT_ON_THREAD(t) do { \ |
|
73 if (t) { \ |
|
74 bool on; \ |
|
75 nsresult rv; \ |
|
76 rv = t->IsOnCurrentThread(&on); \ |
|
77 MOZ_ASSERT(NS_SUCCEEDED(rv)); \ |
|
78 MOZ_ASSERT(on); \ |
|
79 } \ |
|
80 } while(0) |
|
81 #else |
|
82 #define ASSERT_ON_THREAD(t) |
|
83 #endif |
|
84 |
|
85 } /* namespace mozilla */ |
|
86 |
|
87 #endif |