|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim: set ts=8 sts=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 |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #ifndef mozilla_nsDumpUtils_h |
|
8 #define mozilla_nsDumpUtils_h |
|
9 |
|
10 #include "nsIObserver.h" |
|
11 #include "base/message_loop.h" |
|
12 #include "nsXULAppAPI.h" |
|
13 #include "nsThreadUtils.h" |
|
14 #include "mozilla/Mutex.h" |
|
15 #include "mozilla/StaticPtr.h" |
|
16 #include "nsTArray.h" |
|
17 |
|
18 #ifdef LOG |
|
19 #undef LOG |
|
20 #endif |
|
21 |
|
22 #ifdef ANDROID |
|
23 #include "android/log.h" |
|
24 #define LOG(...) __android_log_print(ANDROID_LOG_INFO, "Gecko:DumpUtils", ## __VA_ARGS__) |
|
25 #else |
|
26 #define LOG(...) |
|
27 #endif |
|
28 |
|
29 using namespace mozilla; |
|
30 |
|
31 #ifdef XP_UNIX // { |
|
32 |
|
33 /** |
|
34 * Abstract base class for something which watches an fd and takes action when |
|
35 * we can read from it without blocking. |
|
36 */ |
|
37 class FdWatcher : public MessageLoopForIO::Watcher |
|
38 , public nsIObserver |
|
39 { |
|
40 protected: |
|
41 MessageLoopForIO::FileDescriptorWatcher mReadWatcher; |
|
42 int mFd; |
|
43 |
|
44 public: |
|
45 FdWatcher() |
|
46 : mFd(-1) |
|
47 { |
|
48 MOZ_ASSERT(NS_IsMainThread()); |
|
49 } |
|
50 |
|
51 virtual ~FdWatcher() |
|
52 { |
|
53 // StopWatching should have run. |
|
54 MOZ_ASSERT(mFd == -1); |
|
55 } |
|
56 |
|
57 /** |
|
58 * Open the fd to watch. If we encounter an error, return -1. |
|
59 */ |
|
60 virtual int OpenFd() = 0; |
|
61 |
|
62 /** |
|
63 * Called when you can read() from the fd without blocking. Note that this |
|
64 * function is also called when you're at eof (read() returns 0 in this case). |
|
65 */ |
|
66 virtual void OnFileCanReadWithoutBlocking(int aFd) = 0; |
|
67 virtual void OnFileCanWriteWithoutBlocking(int aFd) {}; |
|
68 |
|
69 NS_DECL_THREADSAFE_ISUPPORTS |
|
70 |
|
71 /** |
|
72 * Initialize this object. This should be called right after the object is |
|
73 * constructed. (This would go in the constructor, except we interact with |
|
74 * XPCOM, which we can't do from a constructor because our refcount is 0 at |
|
75 * that point.) |
|
76 */ |
|
77 void Init(); |
|
78 |
|
79 // Implementations may call this function multiple times if they ensure that |
|
80 |
|
81 virtual void StartWatching(); |
|
82 |
|
83 // Since implementations can call StartWatching() multiple times, they can of |
|
84 // course call StopWatching() multiple times. |
|
85 virtual void StopWatching(); |
|
86 |
|
87 NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic, |
|
88 const char16_t* aData) |
|
89 { |
|
90 MOZ_ASSERT(NS_IsMainThread()); |
|
91 MOZ_ASSERT(!strcmp(aTopic, "xpcom-shutdown")); |
|
92 |
|
93 XRE_GetIOMessageLoop()->PostTask( |
|
94 FROM_HERE, |
|
95 NewRunnableMethod(this, &FdWatcher::StopWatching)); |
|
96 |
|
97 return NS_OK; |
|
98 } |
|
99 }; |
|
100 |
|
101 typedef void (* FifoCallback)(const nsCString& inputStr); |
|
102 struct FifoInfo { |
|
103 nsCString mCommand; |
|
104 FifoCallback mCallback; |
|
105 }; |
|
106 typedef nsTArray<FifoInfo> FifoInfoArray; |
|
107 |
|
108 class FifoWatcher : public FdWatcher |
|
109 { |
|
110 public: |
|
111 /** |
|
112 * The name of the preference used to enable/disable the FifoWatcher. |
|
113 */ |
|
114 static const char* const kPrefName; |
|
115 |
|
116 static FifoWatcher* GetSingleton(); |
|
117 |
|
118 static bool MaybeCreate(); |
|
119 |
|
120 void RegisterCallback(const nsCString& aCommand, FifoCallback aCallback); |
|
121 |
|
122 virtual ~FifoWatcher(); |
|
123 |
|
124 virtual int OpenFd(); |
|
125 |
|
126 virtual void OnFileCanReadWithoutBlocking(int aFd); |
|
127 |
|
128 private: |
|
129 nsAutoCString mDirPath; |
|
130 |
|
131 static StaticRefPtr<FifoWatcher> sSingleton; |
|
132 |
|
133 FifoWatcher(nsCString aPath) |
|
134 : mDirPath(aPath) |
|
135 , mFifoInfoLock("FifoWatcher.mFifoInfoLock") |
|
136 {} |
|
137 |
|
138 mozilla::Mutex mFifoInfoLock; // protects mFifoInfo |
|
139 FifoInfoArray mFifoInfo; |
|
140 }; |
|
141 |
|
142 typedef void (* PipeCallback)(const uint8_t recvSig); |
|
143 struct SignalInfo { |
|
144 uint8_t mSignal; |
|
145 PipeCallback mCallback; |
|
146 }; |
|
147 typedef nsTArray<SignalInfo> SignalInfoArray; |
|
148 |
|
149 class SignalPipeWatcher : public FdWatcher |
|
150 { |
|
151 public: |
|
152 static SignalPipeWatcher* GetSingleton(); |
|
153 |
|
154 void RegisterCallback(uint8_t aSignal, PipeCallback aCallback); |
|
155 |
|
156 void RegisterSignalHandler(uint8_t aSignal = 0); |
|
157 |
|
158 virtual ~SignalPipeWatcher(); |
|
159 |
|
160 virtual int OpenFd(); |
|
161 |
|
162 virtual void StopWatching(); |
|
163 |
|
164 virtual void OnFileCanReadWithoutBlocking(int aFd); |
|
165 |
|
166 private: |
|
167 static StaticRefPtr<SignalPipeWatcher> sSingleton; |
|
168 |
|
169 SignalPipeWatcher() |
|
170 : mSignalInfoLock("SignalPipeWatcher.mSignalInfoLock") |
|
171 { |
|
172 MOZ_ASSERT(NS_IsMainThread()); |
|
173 } |
|
174 |
|
175 mozilla::Mutex mSignalInfoLock; // protects mSignalInfo |
|
176 SignalInfoArray mSignalInfo; |
|
177 }; |
|
178 |
|
179 #endif // XP_UNIX } |
|
180 |
|
181 |
|
182 class nsDumpUtils |
|
183 { |
|
184 public: |
|
185 /** |
|
186 * This function creates a new unique file based on |aFilename| in a |
|
187 * world-readable temp directory. This is the system temp directory |
|
188 * or, in the case of Android, the downloads directory. If |aFile| is |
|
189 * non-null, it is assumed to point to a folder, and that folder is used |
|
190 * instead. |
|
191 */ |
|
192 static nsresult OpenTempFile(const nsACString& aFilename, |
|
193 nsIFile** aFile, |
|
194 const nsACString& aFoldername = EmptyCString()); |
|
195 }; |
|
196 |
|
197 #endif |