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