Workers.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  4. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef mozilla_dom_workers_workers_h__
  6. #define mozilla_dom_workers_workers_h__
  7. #include "jsapi.h"
  8. #include "mozilla/Attributes.h"
  9. #include "mozilla/Mutex.h"
  10. #include <stdint.h>
  11. #include "nsAutoPtr.h"
  12. #include "nsCOMPtr.h"
  13. #include "nsDebug.h"
  14. #include "nsString.h"
  15. #include "nsTArray.h"
  16. #include "nsILoadContext.h"
  17. #include "nsIWeakReferenceUtils.h"
  18. #include "nsIInterfaceRequestor.h"
  19. #include "mozilla/dom/ChannelInfo.h"
  20. #include "mozilla/net/ReferrerPolicy.h"
  21. #define BEGIN_WORKERS_NAMESPACE \
  22. namespace mozilla { namespace dom { namespace workers {
  23. #define END_WORKERS_NAMESPACE \
  24. } /* namespace workers */ } /* namespace dom */ } /* namespace mozilla */
  25. #define USING_WORKERS_NAMESPACE \
  26. using namespace mozilla::dom::workers;
  27. #define WORKERS_SHUTDOWN_TOPIC "web-workers-shutdown"
  28. class nsIContentSecurityPolicy;
  29. class nsIScriptContext;
  30. class nsIGlobalObject;
  31. class nsPIDOMWindowInner;
  32. class nsIPrincipal;
  33. class nsILoadGroup;
  34. class nsITabChild;
  35. class nsIChannel;
  36. class nsIRunnable;
  37. class nsIURI;
  38. namespace mozilla {
  39. namespace ipc {
  40. class PrincipalInfo;
  41. } // namespace ipc
  42. namespace dom {
  43. // If you change this, the corresponding list in nsIWorkerDebugger.idl needs to
  44. // be updated too.
  45. enum WorkerType
  46. {
  47. WorkerTypeDedicated,
  48. WorkerTypeShared,
  49. WorkerTypeService
  50. };
  51. } // namespace dom
  52. } // namespace mozilla
  53. BEGIN_WORKERS_NAMESPACE
  54. class WorkerPrivate;
  55. struct PrivatizableBase
  56. { };
  57. #ifdef DEBUG
  58. void
  59. AssertIsOnMainThread();
  60. #else
  61. inline void
  62. AssertIsOnMainThread()
  63. { }
  64. #endif
  65. struct JSSettings
  66. {
  67. enum {
  68. // All the GC parameters that we support.
  69. JSSettings_JSGC_MAX_BYTES = 0,
  70. JSSettings_JSGC_MAX_MALLOC_BYTES,
  71. JSSettings_JSGC_HIGH_FREQUENCY_TIME_LIMIT,
  72. JSSettings_JSGC_LOW_FREQUENCY_HEAP_GROWTH,
  73. JSSettings_JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN,
  74. JSSettings_JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX,
  75. JSSettings_JSGC_HIGH_FREQUENCY_LOW_LIMIT,
  76. JSSettings_JSGC_HIGH_FREQUENCY_HIGH_LIMIT,
  77. JSSettings_JSGC_ALLOCATION_THRESHOLD,
  78. JSSettings_JSGC_SLICE_TIME_BUDGET,
  79. JSSettings_JSGC_DYNAMIC_HEAP_GROWTH,
  80. JSSettings_JSGC_DYNAMIC_MARK_SLICE,
  81. JSSettings_JSGC_REFRESH_FRAME_SLICES,
  82. // JSGC_MODE not supported
  83. // This must be last so that we get an accurate count.
  84. kGCSettingsArraySize
  85. };
  86. struct JSGCSetting
  87. {
  88. JSGCParamKey key;
  89. uint32_t value;
  90. JSGCSetting()
  91. : key(static_cast<JSGCParamKey>(-1)), value(0)
  92. { }
  93. bool
  94. IsSet() const
  95. {
  96. return key != static_cast<JSGCParamKey>(-1);
  97. }
  98. void
  99. Unset()
  100. {
  101. key = static_cast<JSGCParamKey>(-1);
  102. value = 0;
  103. }
  104. };
  105. // There are several settings that we know we need so it makes sense to
  106. // preallocate here.
  107. typedef JSGCSetting JSGCSettingsArray[kGCSettingsArraySize];
  108. // Settings that change based on chrome/content context.
  109. struct JSContentChromeSettings
  110. {
  111. JS::CompartmentOptions compartmentOptions;
  112. int32_t maxScriptRuntime;
  113. JSContentChromeSettings()
  114. : compartmentOptions(), maxScriptRuntime(0)
  115. { }
  116. };
  117. JSContentChromeSettings chrome;
  118. JSContentChromeSettings content;
  119. JSGCSettingsArray gcSettings;
  120. JS::ContextOptions contextOptions;
  121. JSSettings()
  122. {
  123. for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) {
  124. new (gcSettings + index) JSGCSetting();
  125. }
  126. }
  127. bool
  128. ApplyGCSetting(JSGCParamKey aKey, uint32_t aValue)
  129. {
  130. JSSettings::JSGCSetting* firstEmptySetting = nullptr;
  131. JSSettings::JSGCSetting* foundSetting = nullptr;
  132. for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) {
  133. JSSettings::JSGCSetting& setting = gcSettings[index];
  134. if (setting.key == aKey) {
  135. foundSetting = &setting;
  136. break;
  137. }
  138. if (!firstEmptySetting && !setting.IsSet()) {
  139. firstEmptySetting = &setting;
  140. }
  141. }
  142. if (aValue) {
  143. if (!foundSetting) {
  144. foundSetting = firstEmptySetting;
  145. if (!foundSetting) {
  146. NS_ERROR("Not enough space for this value!");
  147. return false;
  148. }
  149. }
  150. foundSetting->key = aKey;
  151. foundSetting->value = aValue;
  152. return true;
  153. }
  154. if (foundSetting) {
  155. foundSetting->Unset();
  156. return true;
  157. }
  158. return false;
  159. }
  160. };
  161. enum WorkerPreference
  162. {
  163. #define WORKER_SIMPLE_PREF(name, getter, NAME) WORKERPREF_ ## NAME,
  164. #define WORKER_PREF(name, callback)
  165. #include "mozilla/dom/WorkerPrefs.h"
  166. #undef WORKER_SIMPLE_PREF
  167. #undef WORKER_PREF
  168. WORKERPREF_COUNT
  169. };
  170. // Implemented in WorkerPrivate.cpp
  171. struct WorkerLoadInfo
  172. {
  173. // All of these should be released in WorkerPrivateParent::ForgetMainThreadObjects.
  174. nsCOMPtr<nsIURI> mBaseURI;
  175. nsCOMPtr<nsIURI> mResolvedScriptURI;
  176. nsCOMPtr<nsIPrincipal> mPrincipal;
  177. nsCOMPtr<nsIScriptContext> mScriptContext;
  178. nsCOMPtr<nsPIDOMWindowInner> mWindow;
  179. nsCOMPtr<nsIContentSecurityPolicy> mCSP;
  180. nsCOMPtr<nsIChannel> mChannel;
  181. nsCOMPtr<nsILoadGroup> mLoadGroup;
  182. // mLoadFailedAsyncRunnable will execute on main thread if script loading
  183. // fails during script loading. If script loading is never started due to
  184. // a synchronous error, then the runnable is never executed. The runnable
  185. // is guaranteed to be released on the main thread.
  186. nsCOMPtr<nsIRunnable> mLoadFailedAsyncRunnable;
  187. class InterfaceRequestor final : public nsIInterfaceRequestor
  188. {
  189. NS_DECL_ISUPPORTS
  190. public:
  191. InterfaceRequestor(nsIPrincipal* aPrincipal, nsILoadGroup* aLoadGroup);
  192. void MaybeAddTabChild(nsILoadGroup* aLoadGroup);
  193. NS_IMETHOD GetInterface(const nsIID& aIID, void** aSink) override;
  194. private:
  195. ~InterfaceRequestor() { }
  196. already_AddRefed<nsITabChild> GetAnyLiveTabChild();
  197. nsCOMPtr<nsILoadContext> mLoadContext;
  198. nsCOMPtr<nsIInterfaceRequestor> mOuterRequestor;
  199. // Array of weak references to nsITabChild. We do not want to keep TabChild
  200. // actors alive for long after their ActorDestroy() methods are called.
  201. nsTArray<nsWeakPtr> mTabChildList;
  202. };
  203. // Only set if we have a custom overriden load group
  204. RefPtr<InterfaceRequestor> mInterfaceRequestor;
  205. nsAutoPtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
  206. nsCString mDomain;
  207. nsString mOrigin; // Derived from mPrincipal; can be used on worker threads.
  208. nsString mServiceWorkerCacheName;
  209. ChannelInfo mChannelInfo;
  210. uint64_t mWindowID;
  211. uint64_t mServiceWorkerID;
  212. net::ReferrerPolicy mReferrerPolicy;
  213. bool mFromWindow;
  214. bool mEvalAllowed;
  215. bool mReportCSPViolations;
  216. bool mXHRParamsAllowed;
  217. bool mPrincipalIsSystem;
  218. bool mStorageAllowed;
  219. bool mServiceWorkersTestingInWindow;
  220. PrincipalOriginAttributes mOriginAttributes;
  221. WorkerLoadInfo();
  222. ~WorkerLoadInfo();
  223. void StealFrom(WorkerLoadInfo& aOther);
  224. };
  225. // All of these are implemented in RuntimeService.cpp
  226. void
  227. CancelWorkersForWindow(nsPIDOMWindowInner* aWindow);
  228. void
  229. FreezeWorkersForWindow(nsPIDOMWindowInner* aWindow);
  230. void
  231. ThawWorkersForWindow(nsPIDOMWindowInner* aWindow);
  232. void
  233. SuspendWorkersForWindow(nsPIDOMWindowInner* aWindow);
  234. void
  235. ResumeWorkersForWindow(nsPIDOMWindowInner* aWindow);
  236. // A class that can be used with WorkerCrossThreadDispatcher to run a
  237. // bit of C++ code on the worker thread.
  238. class WorkerTask
  239. {
  240. protected:
  241. WorkerTask()
  242. { }
  243. virtual ~WorkerTask()
  244. { }
  245. public:
  246. NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WorkerTask)
  247. // The return value here has the same semantics as the return value
  248. // of WorkerRunnable::WorkerRun.
  249. virtual bool
  250. RunTask(JSContext* aCx) = 0;
  251. };
  252. class WorkerCrossThreadDispatcher
  253. {
  254. friend class WorkerPrivate;
  255. // Must be acquired *before* the WorkerPrivate's mutex, when they're both
  256. // held.
  257. Mutex mMutex;
  258. WorkerPrivate* mWorkerPrivate;
  259. private:
  260. // Only created by WorkerPrivate.
  261. explicit WorkerCrossThreadDispatcher(WorkerPrivate* aWorkerPrivate);
  262. // Only called by WorkerPrivate.
  263. void
  264. Forget()
  265. {
  266. MutexAutoLock lock(mMutex);
  267. mWorkerPrivate = nullptr;
  268. }
  269. ~WorkerCrossThreadDispatcher() {}
  270. public:
  271. NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WorkerCrossThreadDispatcher)
  272. // Generically useful function for running a bit of C++ code on the worker
  273. // thread.
  274. bool
  275. PostTask(WorkerTask* aTask);
  276. };
  277. WorkerCrossThreadDispatcher*
  278. GetWorkerCrossThreadDispatcher(JSContext* aCx, const JS::Value& aWorker);
  279. // Random unique constant to facilitate JSPrincipal debugging
  280. const uint32_t kJSPrincipalsDebugToken = 0x7e2df9d2;
  281. namespace exceptions {
  282. // Implemented in Exceptions.cpp
  283. void
  284. ThrowDOMExceptionForNSResult(JSContext* aCx, nsresult aNSResult);
  285. } // namespace exceptions
  286. bool
  287. IsWorkerGlobal(JSObject* global);
  288. bool
  289. IsDebuggerGlobal(JSObject* global);
  290. bool
  291. IsDebuggerSandbox(JSObject* object);
  292. END_WORKERS_NAMESPACE
  293. #endif // mozilla_dom_workers_workers_h__