dom/workers/WorkerPrivate.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef mozilla_dom_workers_workerprivate_h__
michael@0 7 #define mozilla_dom_workers_workerprivate_h__
michael@0 8
michael@0 9 #include "Workers.h"
michael@0 10
michael@0 11 #include "nsIContentSecurityPolicy.h"
michael@0 12 #include "nsPIDOMWindow.h"
michael@0 13
michael@0 14 #include "mozilla/CondVar.h"
michael@0 15 #include "mozilla/DOMEventTargetHelper.h"
michael@0 16 #include "mozilla/TimeStamp.h"
michael@0 17 #include "mozilla/dom/BindingDeclarations.h"
michael@0 18 #include "nsCycleCollectionParticipant.h"
michael@0 19 #include "nsDataHashtable.h"
michael@0 20 #include "nsHashKeys.h"
michael@0 21 #include "nsRefPtrHashtable.h"
michael@0 22 #include "nsString.h"
michael@0 23 #include "nsTArray.h"
michael@0 24 #include "nsThreadUtils.h"
michael@0 25 #include "StructuredCloneTags.h"
michael@0 26
michael@0 27 #include "Queue.h"
michael@0 28 #include "WorkerFeature.h"
michael@0 29
michael@0 30 class JSAutoStructuredCloneBuffer;
michael@0 31 class nsIChannel;
michael@0 32 class nsIDocument;
michael@0 33 class nsIEventTarget;
michael@0 34 class nsIPrincipal;
michael@0 35 class nsIScriptContext;
michael@0 36 class nsIThread;
michael@0 37 class nsIThreadInternal;
michael@0 38 class nsITimer;
michael@0 39 class nsIURI;
michael@0 40
michael@0 41 namespace JS {
michael@0 42 class RuntimeStats;
michael@0 43 }
michael@0 44
michael@0 45 namespace mozilla {
michael@0 46 namespace dom {
michael@0 47 class Function;
michael@0 48 }
michael@0 49 }
michael@0 50
michael@0 51 #ifdef DEBUG
michael@0 52 struct PRThread;
michael@0 53 #endif
michael@0 54
michael@0 55 BEGIN_WORKERS_NAMESPACE
michael@0 56
michael@0 57 class AutoSyncLoopHolder;
michael@0 58 class MessagePort;
michael@0 59 class SharedWorker;
michael@0 60 class WorkerControlRunnable;
michael@0 61 class WorkerGlobalScope;
michael@0 62 class WorkerPrivate;
michael@0 63 class WorkerRunnable;
michael@0 64
michael@0 65 // SharedMutex is a small wrapper around an (internal) reference-counted Mutex
michael@0 66 // object. It exists to avoid changing a lot of code to use Mutex* instead of
michael@0 67 // Mutex&.
michael@0 68 class SharedMutex
michael@0 69 {
michael@0 70 typedef mozilla::Mutex Mutex;
michael@0 71
michael@0 72 class RefCountedMutex MOZ_FINAL : public Mutex
michael@0 73 {
michael@0 74 public:
michael@0 75 RefCountedMutex(const char* aName)
michael@0 76 : Mutex(aName)
michael@0 77 { }
michael@0 78
michael@0 79 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefCountedMutex)
michael@0 80
michael@0 81 private:
michael@0 82 ~RefCountedMutex()
michael@0 83 { }
michael@0 84 };
michael@0 85
michael@0 86 nsRefPtr<RefCountedMutex> mMutex;
michael@0 87
michael@0 88 public:
michael@0 89 SharedMutex(const char* aName)
michael@0 90 : mMutex(new RefCountedMutex(aName))
michael@0 91 { }
michael@0 92
michael@0 93 SharedMutex(SharedMutex& aOther)
michael@0 94 : mMutex(aOther.mMutex)
michael@0 95 { }
michael@0 96
michael@0 97 operator Mutex&()
michael@0 98 {
michael@0 99 return *mMutex;
michael@0 100 }
michael@0 101
michael@0 102 operator const Mutex&() const
michael@0 103 {
michael@0 104 return *mMutex;
michael@0 105 }
michael@0 106
michael@0 107 void
michael@0 108 AssertCurrentThreadOwns() const
michael@0 109 {
michael@0 110 mMutex->AssertCurrentThreadOwns();
michael@0 111 }
michael@0 112 };
michael@0 113
michael@0 114 template <class Derived>
michael@0 115 class WorkerPrivateParent : public DOMEventTargetHelper
michael@0 116 {
michael@0 117 class SynchronizeAndResumeRunnable;
michael@0 118
michael@0 119 protected:
michael@0 120 class EventTarget;
michael@0 121 friend class EventTarget;
michael@0 122
michael@0 123 public:
michael@0 124 struct LocationInfo
michael@0 125 {
michael@0 126 nsCString mHref;
michael@0 127 nsCString mProtocol;
michael@0 128 nsCString mHost;
michael@0 129 nsCString mHostname;
michael@0 130 nsCString mPort;
michael@0 131 nsCString mPathname;
michael@0 132 nsCString mSearch;
michael@0 133 nsCString mHash;
michael@0 134 nsString mOrigin;
michael@0 135 };
michael@0 136
michael@0 137 struct LoadInfo
michael@0 138 {
michael@0 139 // All of these should be released in ForgetMainThreadObjects.
michael@0 140 nsCOMPtr<nsIURI> mBaseURI;
michael@0 141 nsCOMPtr<nsIURI> mResolvedScriptURI;
michael@0 142 nsCOMPtr<nsIPrincipal> mPrincipal;
michael@0 143 nsCOMPtr<nsIScriptContext> mScriptContext;
michael@0 144 nsCOMPtr<nsPIDOMWindow> mWindow;
michael@0 145 nsCOMPtr<nsIContentSecurityPolicy> mCSP;
michael@0 146 nsCOMPtr<nsIChannel> mChannel;
michael@0 147
michael@0 148 nsCString mDomain;
michael@0 149
michael@0 150 bool mEvalAllowed;
michael@0 151 bool mReportCSPViolations;
michael@0 152 bool mXHRParamsAllowed;
michael@0 153 bool mPrincipalIsSystem;
michael@0 154 bool mIsInPrivilegedApp;
michael@0 155 bool mIsInCertifiedApp;
michael@0 156
michael@0 157 LoadInfo()
michael@0 158 : mEvalAllowed(false), mReportCSPViolations(false),
michael@0 159 mXHRParamsAllowed(false), mPrincipalIsSystem(false),
michael@0 160 mIsInPrivilegedApp(false), mIsInCertifiedApp(false)
michael@0 161 { }
michael@0 162
michael@0 163 void
michael@0 164 StealFrom(LoadInfo& aOther)
michael@0 165 {
michael@0 166 MOZ_ASSERT(!mBaseURI);
michael@0 167 aOther.mBaseURI.swap(mBaseURI);
michael@0 168
michael@0 169 MOZ_ASSERT(!mResolvedScriptURI);
michael@0 170 aOther.mResolvedScriptURI.swap(mResolvedScriptURI);
michael@0 171
michael@0 172 MOZ_ASSERT(!mPrincipal);
michael@0 173 aOther.mPrincipal.swap(mPrincipal);
michael@0 174
michael@0 175 MOZ_ASSERT(!mScriptContext);
michael@0 176 aOther.mScriptContext.swap(mScriptContext);
michael@0 177
michael@0 178 MOZ_ASSERT(!mWindow);
michael@0 179 aOther.mWindow.swap(mWindow);
michael@0 180
michael@0 181 MOZ_ASSERT(!mCSP);
michael@0 182 aOther.mCSP.swap(mCSP);
michael@0 183
michael@0 184 MOZ_ASSERT(!mChannel);
michael@0 185 aOther.mChannel.swap(mChannel);
michael@0 186
michael@0 187 mDomain = aOther.mDomain;
michael@0 188 mEvalAllowed = aOther.mEvalAllowed;
michael@0 189 mReportCSPViolations = aOther.mReportCSPViolations;
michael@0 190 mXHRParamsAllowed = aOther.mXHRParamsAllowed;
michael@0 191 mPrincipalIsSystem = aOther.mPrincipalIsSystem;
michael@0 192 mIsInPrivilegedApp = aOther.mIsInPrivilegedApp;
michael@0 193 mIsInCertifiedApp = aOther.mIsInCertifiedApp;
michael@0 194 }
michael@0 195 };
michael@0 196
michael@0 197 enum WorkerType
michael@0 198 {
michael@0 199 WorkerTypeDedicated,
michael@0 200 WorkerTypeShared
michael@0 201 };
michael@0 202
michael@0 203 protected:
michael@0 204 typedef mozilla::ErrorResult ErrorResult;
michael@0 205
michael@0 206 SharedMutex mMutex;
michael@0 207 mozilla::CondVar mCondVar;
michael@0 208 mozilla::CondVar mMemoryReportCondVar;
michael@0 209
michael@0 210 // Protected by mMutex.
michael@0 211 nsRefPtr<EventTarget> mEventTarget;
michael@0 212 nsTArray<nsRefPtr<WorkerRunnable>> mPreStartRunnables;
michael@0 213
michael@0 214 private:
michael@0 215 WorkerPrivate* mParent;
michael@0 216 nsString mScriptURL;
michael@0 217 nsCString mSharedWorkerName;
michael@0 218 LocationInfo mLocationInfo;
michael@0 219 // The lifetime of these objects within LoadInfo is managed explicitly;
michael@0 220 // they do not need to be cycle collected.
michael@0 221 LoadInfo mLoadInfo;
michael@0 222
michael@0 223 // Only used for top level workers.
michael@0 224 nsTArray<nsCOMPtr<nsIRunnable>> mQueuedRunnables;
michael@0 225 nsRevocableEventPtr<SynchronizeAndResumeRunnable> mSynchronizeRunnable;
michael@0 226
michael@0 227 // Only for ChromeWorkers without window and only touched on the main thread.
michael@0 228 nsTArray<nsCString> mHostObjectURIs;
michael@0 229
michael@0 230 // Protected by mMutex.
michael@0 231 JSSettings mJSSettings;
michael@0 232
michael@0 233 // Only touched on the parent thread (currently this is always the main
michael@0 234 // thread as SharedWorkers are always top-level).
michael@0 235 nsDataHashtable<nsUint64HashKey, SharedWorker*> mSharedWorkers;
michael@0 236
michael@0 237 uint64_t mBusyCount;
michael@0 238 uint64_t mMessagePortSerial;
michael@0 239 Status mParentStatus;
michael@0 240 bool mParentSuspended;
michael@0 241 bool mIsChromeWorker;
michael@0 242 bool mMainThreadObjectsForgotten;
michael@0 243 WorkerType mWorkerType;
michael@0 244 TimeStamp mCreationTimeStamp;
michael@0 245
michael@0 246 protected:
michael@0 247 // The worker is owned by its thread, which is represented here. This is set
michael@0 248 // in Construct() and emptied by WorkerFinishedRunnable, and conditionally
michael@0 249 // traversed by the cycle collector if the busy count is zero.
michael@0 250 nsRefPtr<WorkerPrivate> mSelfRef;
michael@0 251
michael@0 252 WorkerPrivateParent(JSContext* aCx, WorkerPrivate* aParent,
michael@0 253 const nsAString& aScriptURL, bool aIsChromeWorker,
michael@0 254 WorkerType aWorkerType,
michael@0 255 const nsACString& aSharedWorkerName,
michael@0 256 LoadInfo& aLoadInfo);
michael@0 257
michael@0 258 ~WorkerPrivateParent();
michael@0 259
michael@0 260 private:
michael@0 261 Derived*
michael@0 262 ParentAsWorkerPrivate() const
michael@0 263 {
michael@0 264 return static_cast<Derived*>(const_cast<WorkerPrivateParent*>(this));
michael@0 265 }
michael@0 266
michael@0 267 // aCx is null when called from the finalizer
michael@0 268 bool
michael@0 269 NotifyPrivate(JSContext* aCx, Status aStatus);
michael@0 270
michael@0 271 // aCx is null when called from the finalizer
michael@0 272 bool
michael@0 273 TerminatePrivate(JSContext* aCx)
michael@0 274 {
michael@0 275 return NotifyPrivate(aCx, Terminating);
michael@0 276 }
michael@0 277
michael@0 278 void
michael@0 279 PostMessageInternal(JSContext* aCx, JS::Handle<JS::Value> aMessage,
michael@0 280 const Optional<Sequence<JS::Value> >& aTransferable,
michael@0 281 bool aToMessagePort, uint64_t aMessagePortSerial,
michael@0 282 ErrorResult& aRv);
michael@0 283
michael@0 284 nsresult
michael@0 285 DispatchPrivate(WorkerRunnable* aRunnable, nsIEventTarget* aSyncLoopTarget);
michael@0 286
michael@0 287 public:
michael@0 288 virtual JSObject*
michael@0 289 WrapObject(JSContext* aCx) MOZ_OVERRIDE;
michael@0 290
michael@0 291 NS_DECL_ISUPPORTS_INHERITED
michael@0 292 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WorkerPrivateParent,
michael@0 293 DOMEventTargetHelper)
michael@0 294
michael@0 295 void
michael@0 296 ClearSelfRef()
michael@0 297 {
michael@0 298 AssertIsOnParentThread();
michael@0 299 MOZ_ASSERT(mSelfRef);
michael@0 300 mSelfRef = nullptr;
michael@0 301 }
michael@0 302
michael@0 303 nsresult
michael@0 304 Dispatch(WorkerRunnable* aRunnable)
michael@0 305 {
michael@0 306 return DispatchPrivate(aRunnable, nullptr);
michael@0 307 }
michael@0 308
michael@0 309 nsresult
michael@0 310 DispatchControlRunnable(WorkerControlRunnable* aWorkerControlRunnable);
michael@0 311
michael@0 312 already_AddRefed<WorkerRunnable>
michael@0 313 MaybeWrapAsWorkerRunnable(nsIRunnable* aRunnable);
michael@0 314
michael@0 315 already_AddRefed<nsIEventTarget>
michael@0 316 GetEventTarget();
michael@0 317
michael@0 318 // May be called on any thread...
michael@0 319 bool
michael@0 320 Start();
michael@0 321
michael@0 322 // Called on the parent thread.
michael@0 323 bool
michael@0 324 Notify(JSContext* aCx, Status aStatus)
michael@0 325 {
michael@0 326 return NotifyPrivate(aCx, aStatus);
michael@0 327 }
michael@0 328
michael@0 329 bool
michael@0 330 Cancel(JSContext* aCx)
michael@0 331 {
michael@0 332 return Notify(aCx, Canceling);
michael@0 333 }
michael@0 334
michael@0 335 bool
michael@0 336 Kill(JSContext* aCx)
michael@0 337 {
michael@0 338 return Notify(aCx, Killing);
michael@0 339 }
michael@0 340
michael@0 341 bool
michael@0 342 Suspend(JSContext* aCx, nsPIDOMWindow* aWindow);
michael@0 343
michael@0 344 bool
michael@0 345 Resume(JSContext* aCx, nsPIDOMWindow* aWindow);
michael@0 346
michael@0 347 bool
michael@0 348 SynchronizeAndResume(JSContext* aCx, nsPIDOMWindow* aWindow,
michael@0 349 nsIScriptContext* aScriptContext);
michael@0 350
michael@0 351 bool
michael@0 352 Terminate(JSContext* aCx)
michael@0 353 {
michael@0 354 AssertIsOnParentThread();
michael@0 355 return TerminatePrivate(aCx);
michael@0 356 }
michael@0 357
michael@0 358 bool
michael@0 359 Close(JSContext* aCx);
michael@0 360
michael@0 361 bool
michael@0 362 ModifyBusyCount(JSContext* aCx, bool aIncrease);
michael@0 363
michael@0 364 void
michael@0 365 ForgetMainThreadObjects(nsTArray<nsCOMPtr<nsISupports> >& aDoomed);
michael@0 366
michael@0 367 void
michael@0 368 PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
michael@0 369 const Optional<Sequence<JS::Value> >& aTransferable,
michael@0 370 ErrorResult& aRv)
michael@0 371 {
michael@0 372 PostMessageInternal(aCx, aMessage, aTransferable, false, 0, aRv);
michael@0 373 }
michael@0 374
michael@0 375 void
michael@0 376 PostMessageToMessagePort(JSContext* aCx,
michael@0 377 uint64_t aMessagePortSerial,
michael@0 378 JS::Handle<JS::Value> aMessage,
michael@0 379 const Optional<Sequence<JS::Value> >& aTransferable,
michael@0 380 ErrorResult& aRv);
michael@0 381
michael@0 382 bool
michael@0 383 DispatchMessageEventToMessagePort(
michael@0 384 JSContext* aCx,
michael@0 385 uint64_t aMessagePortSerial,
michael@0 386 JSAutoStructuredCloneBuffer&& aBuffer,
michael@0 387 nsTArray<nsCOMPtr<nsISupports>>& aClonedObjects);
michael@0 388
michael@0 389 uint64_t
michael@0 390 GetInnerWindowId();
michael@0 391
michael@0 392 void
michael@0 393 UpdateRuntimeAndContextOptions(JSContext* aCx,
michael@0 394 const JS::RuntimeOptions& aRuntimeOptions,
michael@0 395 const JS::ContextOptions& aContentCxOptions,
michael@0 396 const JS::ContextOptions& aChromeCxOptions);
michael@0 397
michael@0 398 void
michael@0 399 UpdatePreference(JSContext* aCx, WorkerPreference aPref, bool aValue);
michael@0 400
michael@0 401 void
michael@0 402 UpdateJSWorkerMemoryParameter(JSContext* aCx, JSGCParamKey key,
michael@0 403 uint32_t value);
michael@0 404
michael@0 405 #ifdef JS_GC_ZEAL
michael@0 406 void
michael@0 407 UpdateGCZeal(JSContext* aCx, uint8_t aGCZeal, uint32_t aFrequency);
michael@0 408 #endif
michael@0 409
michael@0 410 void
michael@0 411 GarbageCollect(JSContext* aCx, bool aShrinking);
michael@0 412
michael@0 413 void
michael@0 414 CycleCollect(JSContext* aCx, bool aDummy);
michael@0 415
michael@0 416 void
michael@0 417 OfflineStatusChangeEvent(JSContext* aCx, bool aIsOffline);
michael@0 418
michael@0 419 bool
michael@0 420 RegisterSharedWorker(JSContext* aCx, SharedWorker* aSharedWorker);
michael@0 421
michael@0 422 void
michael@0 423 UnregisterSharedWorker(JSContext* aCx, SharedWorker* aSharedWorker);
michael@0 424
michael@0 425 void
michael@0 426 BroadcastErrorToSharedWorkers(JSContext* aCx,
michael@0 427 const nsAString& aMessage,
michael@0 428 const nsAString& aFilename,
michael@0 429 const nsAString& aLine,
michael@0 430 uint32_t aLineNumber,
michael@0 431 uint32_t aColumnNumber,
michael@0 432 uint32_t aFlags);
michael@0 433
michael@0 434 void
michael@0 435 WorkerScriptLoaded();
michael@0 436
michael@0 437 void
michael@0 438 QueueRunnable(nsIRunnable* aRunnable)
michael@0 439 {
michael@0 440 AssertIsOnMainThread();
michael@0 441 mQueuedRunnables.AppendElement(aRunnable);
michael@0 442 }
michael@0 443
michael@0 444 WorkerPrivate*
michael@0 445 GetParent() const
michael@0 446 {
michael@0 447 return mParent;
michael@0 448 }
michael@0 449
michael@0 450 bool
michael@0 451 IsSuspended() const
michael@0 452 {
michael@0 453 AssertIsOnParentThread();
michael@0 454 return mParentSuspended;
michael@0 455 }
michael@0 456
michael@0 457 bool
michael@0 458 IsAcceptingEvents()
michael@0 459 {
michael@0 460 AssertIsOnParentThread();
michael@0 461
michael@0 462 MutexAutoLock lock(mMutex);
michael@0 463 return mParentStatus < Terminating;
michael@0 464 }
michael@0 465
michael@0 466 Status
michael@0 467 ParentStatus() const
michael@0 468 {
michael@0 469 mMutex.AssertCurrentThreadOwns();
michael@0 470 return mParentStatus;
michael@0 471 }
michael@0 472
michael@0 473 JSContext*
michael@0 474 ParentJSContext() const;
michael@0 475
michael@0 476 nsIScriptContext*
michael@0 477 GetScriptContext() const
michael@0 478 {
michael@0 479 AssertIsOnMainThread();
michael@0 480 return mLoadInfo.mScriptContext;
michael@0 481 }
michael@0 482
michael@0 483 const nsString&
michael@0 484 ScriptURL() const
michael@0 485 {
michael@0 486 return mScriptURL;
michael@0 487 }
michael@0 488
michael@0 489 const nsCString&
michael@0 490 Domain() const
michael@0 491 {
michael@0 492 return mLoadInfo.mDomain;
michael@0 493 }
michael@0 494
michael@0 495 nsIURI*
michael@0 496 GetBaseURI() const
michael@0 497 {
michael@0 498 AssertIsOnMainThread();
michael@0 499 return mLoadInfo.mBaseURI;
michael@0 500 }
michael@0 501
michael@0 502 void
michael@0 503 SetBaseURI(nsIURI* aBaseURI);
michael@0 504
michael@0 505 nsIURI*
michael@0 506 GetResolvedScriptURI() const
michael@0 507 {
michael@0 508 AssertIsOnMainThread();
michael@0 509 return mLoadInfo.mResolvedScriptURI;
michael@0 510 }
michael@0 511
michael@0 512 TimeStamp CreationTimeStamp() const
michael@0 513 {
michael@0 514 return mCreationTimeStamp;
michael@0 515 }
michael@0 516
michael@0 517 nsIPrincipal*
michael@0 518 GetPrincipal() const
michael@0 519 {
michael@0 520 AssertIsOnMainThread();
michael@0 521 return mLoadInfo.mPrincipal;
michael@0 522 }
michael@0 523
michael@0 524 // This method allows the principal to be retrieved off the main thread.
michael@0 525 // Principals are main-thread objects so the caller must ensure that all
michael@0 526 // access occurs on the main thread.
michael@0 527 nsIPrincipal*
michael@0 528 GetPrincipalDontAssertMainThread() const
michael@0 529 {
michael@0 530 return mLoadInfo.mPrincipal;
michael@0 531 }
michael@0 532
michael@0 533 void
michael@0 534 SetPrincipal(nsIPrincipal* aPrincipal);
michael@0 535
michael@0 536 bool
michael@0 537 UsesSystemPrincipal() const
michael@0 538 {
michael@0 539 return mLoadInfo.mPrincipalIsSystem;
michael@0 540 }
michael@0 541
michael@0 542 bool
michael@0 543 IsInPrivilegedApp() const
michael@0 544 {
michael@0 545 return mLoadInfo.mIsInPrivilegedApp;
michael@0 546 }
michael@0 547
michael@0 548 bool
michael@0 549 IsInCertifiedApp() const
michael@0 550 {
michael@0 551 return mLoadInfo.mIsInCertifiedApp;
michael@0 552 }
michael@0 553
michael@0 554 already_AddRefed<nsIChannel>
michael@0 555 ForgetWorkerChannel()
michael@0 556 {
michael@0 557 AssertIsOnMainThread();
michael@0 558 return mLoadInfo.mChannel.forget();
michael@0 559 }
michael@0 560
michael@0 561 nsIDocument*
michael@0 562 GetDocument() const
michael@0 563 {
michael@0 564 AssertIsOnMainThread();
michael@0 565 return mLoadInfo.mWindow ? mLoadInfo.mWindow->GetExtantDoc() : nullptr;
michael@0 566 }
michael@0 567
michael@0 568 nsPIDOMWindow*
michael@0 569 GetWindow()
michael@0 570 {
michael@0 571 AssertIsOnMainThread();
michael@0 572 return mLoadInfo.mWindow;
michael@0 573 }
michael@0 574
michael@0 575 nsIContentSecurityPolicy*
michael@0 576 GetCSP() const
michael@0 577 {
michael@0 578 AssertIsOnMainThread();
michael@0 579 return mLoadInfo.mCSP;
michael@0 580 }
michael@0 581
michael@0 582 void
michael@0 583 SetCSP(nsIContentSecurityPolicy* aCSP)
michael@0 584 {
michael@0 585 AssertIsOnMainThread();
michael@0 586 mLoadInfo.mCSP = aCSP;
michael@0 587 }
michael@0 588
michael@0 589 bool
michael@0 590 IsEvalAllowed() const
michael@0 591 {
michael@0 592 return mLoadInfo.mEvalAllowed;
michael@0 593 }
michael@0 594
michael@0 595 void
michael@0 596 SetEvalAllowed(bool aEvalAllowed)
michael@0 597 {
michael@0 598 mLoadInfo.mEvalAllowed = aEvalAllowed;
michael@0 599 }
michael@0 600
michael@0 601 bool
michael@0 602 GetReportCSPViolations() const
michael@0 603 {
michael@0 604 return mLoadInfo.mReportCSPViolations;
michael@0 605 }
michael@0 606
michael@0 607 bool
michael@0 608 XHRParamsAllowed() const
michael@0 609 {
michael@0 610 return mLoadInfo.mXHRParamsAllowed;
michael@0 611 }
michael@0 612
michael@0 613 void
michael@0 614 SetXHRParamsAllowed(bool aAllowed)
michael@0 615 {
michael@0 616 mLoadInfo.mXHRParamsAllowed = aAllowed;
michael@0 617 }
michael@0 618
michael@0 619 LocationInfo&
michael@0 620 GetLocationInfo()
michael@0 621 {
michael@0 622 return mLocationInfo;
michael@0 623 }
michael@0 624
michael@0 625 void
michael@0 626 CopyJSSettings(JSSettings& aSettings)
michael@0 627 {
michael@0 628 mozilla::MutexAutoLock lock(mMutex);
michael@0 629 aSettings = mJSSettings;
michael@0 630 }
michael@0 631
michael@0 632 void
michael@0 633 CopyJSCompartmentOptions(JS::CompartmentOptions& aOptions)
michael@0 634 {
michael@0 635 mozilla::MutexAutoLock lock(mMutex);
michael@0 636 aOptions = IsChromeWorker() ? mJSSettings.chrome.compartmentOptions
michael@0 637 : mJSSettings.content.compartmentOptions;
michael@0 638 }
michael@0 639
michael@0 640 // The ability to be a chrome worker is orthogonal to the type of
michael@0 641 // worker [Dedicated|Shared].
michael@0 642 bool
michael@0 643 IsChromeWorker() const
michael@0 644 {
michael@0 645 return mIsChromeWorker;
michael@0 646 }
michael@0 647
michael@0 648 bool
michael@0 649 IsDedicatedWorker() const
michael@0 650 {
michael@0 651 return mWorkerType == WorkerTypeDedicated;
michael@0 652 }
michael@0 653
michael@0 654 bool
michael@0 655 IsSharedWorker() const
michael@0 656 {
michael@0 657 return mWorkerType == WorkerTypeShared;
michael@0 658 }
michael@0 659
michael@0 660 const nsCString&
michael@0 661 SharedWorkerName() const
michael@0 662 {
michael@0 663 return mSharedWorkerName;
michael@0 664 }
michael@0 665
michael@0 666 uint64_t
michael@0 667 NextMessagePortSerial()
michael@0 668 {
michael@0 669 AssertIsOnMainThread();
michael@0 670 return mMessagePortSerial++;
michael@0 671 }
michael@0 672
michael@0 673 void
michael@0 674 GetAllSharedWorkers(nsTArray<nsRefPtr<SharedWorker>>& aSharedWorkers);
michael@0 675
michael@0 676 void
michael@0 677 CloseSharedWorkersForWindow(nsPIDOMWindow* aWindow);
michael@0 678
michael@0 679 void
michael@0 680 RegisterHostObjectURI(const nsACString& aURI);
michael@0 681
michael@0 682 void
michael@0 683 UnregisterHostObjectURI(const nsACString& aURI);
michael@0 684
michael@0 685 void
michael@0 686 StealHostObjectURIs(nsTArray<nsCString>& aArray);
michael@0 687
michael@0 688 IMPL_EVENT_HANDLER(message)
michael@0 689 IMPL_EVENT_HANDLER(error)
michael@0 690
michael@0 691 #ifdef DEBUG
michael@0 692 void
michael@0 693 AssertIsOnParentThread() const;
michael@0 694
michael@0 695 void
michael@0 696 AssertInnerWindowIsCorrect() const;
michael@0 697 #else
michael@0 698 void
michael@0 699 AssertIsOnParentThread() const
michael@0 700 { }
michael@0 701
michael@0 702 void
michael@0 703 AssertInnerWindowIsCorrect() const
michael@0 704 { }
michael@0 705 #endif
michael@0 706 };
michael@0 707
michael@0 708 class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
michael@0 709 {
michael@0 710 friend class WorkerPrivateParent<WorkerPrivate>;
michael@0 711 typedef WorkerPrivateParent<WorkerPrivate> ParentType;
michael@0 712 friend class AutoSyncLoopHolder;
michael@0 713
michael@0 714 struct TimeoutInfo;
michael@0 715
michael@0 716 class MemoryReporter;
michael@0 717 friend class MemoryReporter;
michael@0 718
michael@0 719 enum GCTimerMode
michael@0 720 {
michael@0 721 PeriodicTimer = 0,
michael@0 722 IdleTimer,
michael@0 723 NoTimer
michael@0 724 };
michael@0 725
michael@0 726 Queue<WorkerControlRunnable*, 4> mControlQueue;
michael@0 727
michael@0 728 // Touched on multiple threads, protected with mMutex.
michael@0 729 JSContext* mJSContext;
michael@0 730 nsRefPtr<WorkerCrossThreadDispatcher> mCrossThreadDispatcher;
michael@0 731 nsTArray<nsCOMPtr<nsIRunnable>> mUndispatchedRunnablesForSyncLoop;
michael@0 732 nsCOMPtr<nsIThread> mThread;
michael@0 733
michael@0 734 // Things touched on worker thread only.
michael@0 735 nsRefPtr<WorkerGlobalScope> mScope;
michael@0 736 nsTArray<ParentType*> mChildWorkers;
michael@0 737 nsTArray<WorkerFeature*> mFeatures;
michael@0 738 nsTArray<nsAutoPtr<TimeoutInfo>> mTimeouts;
michael@0 739
michael@0 740 struct SyncLoopInfo
michael@0 741 {
michael@0 742 SyncLoopInfo(EventTarget* aEventTarget);
michael@0 743
michael@0 744 nsRefPtr<EventTarget> mEventTarget;
michael@0 745 bool mCompleted;
michael@0 746 bool mResult;
michael@0 747 #ifdef DEBUG
michael@0 748 bool mHasRun;
michael@0 749 #endif
michael@0 750 };
michael@0 751
michael@0 752 // This is only modified on the worker thread, but in DEBUG builds
michael@0 753 // AssertValidSyncLoop function iterates it on other threads. Therefore
michael@0 754 // modifications are done with mMutex held *only* in DEBUG builds.
michael@0 755 nsTArray<nsAutoPtr<SyncLoopInfo>> mSyncLoopStack;
michael@0 756
michael@0 757 nsCOMPtr<nsITimer> mTimer;
michael@0 758
michael@0 759 nsCOMPtr<nsITimer> mGCTimer;
michael@0 760 nsCOMPtr<nsIEventTarget> mPeriodicGCTimerTarget;
michael@0 761 nsCOMPtr<nsIEventTarget> mIdleGCTimerTarget;
michael@0 762
michael@0 763 nsRefPtr<MemoryReporter> mMemoryReporter;
michael@0 764
michael@0 765 nsRefPtrHashtable<nsUint64HashKey, MessagePort> mWorkerPorts;
michael@0 766
michael@0 767 TimeStamp mKillTime;
michael@0 768 uint32_t mErrorHandlerRecursionCount;
michael@0 769 uint32_t mNextTimeoutId;
michael@0 770 Status mStatus;
michael@0 771 bool mSuspended;
michael@0 772 bool mTimerRunning;
michael@0 773 bool mRunningExpiredTimeouts;
michael@0 774 bool mCloseHandlerStarted;
michael@0 775 bool mCloseHandlerFinished;
michael@0 776 bool mMemoryReporterRunning;
michael@0 777 bool mBlockedForMemoryReporter;
michael@0 778 bool mCancelAllPendingRunnables;
michael@0 779 bool mPeriodicGCTimerRunning;
michael@0 780 bool mIdleGCTimerRunning;
michael@0 781
michael@0 782 #ifdef DEBUG
michael@0 783 PRThread* mPRThread;
michael@0 784 #endif
michael@0 785
michael@0 786 bool mPreferences[WORKERPREF_COUNT];
michael@0 787 bool mOnLine;
michael@0 788
michael@0 789 protected:
michael@0 790 ~WorkerPrivate();
michael@0 791
michael@0 792 public:
michael@0 793 static already_AddRefed<WorkerPrivate>
michael@0 794 Constructor(const GlobalObject& aGlobal, const nsAString& aScriptURL,
michael@0 795 ErrorResult& aRv);
michael@0 796
michael@0 797 static already_AddRefed<WorkerPrivate>
michael@0 798 Constructor(const GlobalObject& aGlobal, const nsAString& aScriptURL,
michael@0 799 bool aIsChromeWorker, WorkerType aWorkerType,
michael@0 800 const nsACString& aSharedWorkerName,
michael@0 801 LoadInfo* aLoadInfo, ErrorResult& aRv);
michael@0 802
michael@0 803 static bool
michael@0 804 WorkerAvailable(JSContext* /* unused */, JSObject* /* unused */);
michael@0 805
michael@0 806 static nsresult
michael@0 807 GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow, WorkerPrivate* aParent,
michael@0 808 const nsAString& aScriptURL, bool aIsChromeWorker,
michael@0 809 LoadInfo* aLoadInfo);
michael@0 810
michael@0 811 void
michael@0 812 DoRunLoop(JSContext* aCx);
michael@0 813
michael@0 814 bool
michael@0 815 InterruptCallback(JSContext* aCx);
michael@0 816
michael@0 817 nsresult
michael@0 818 IsOnCurrentThread(bool* aIsOnCurrentThread);
michael@0 819
michael@0 820 bool
michael@0 821 CloseInternal(JSContext* aCx)
michael@0 822 {
michael@0 823 AssertIsOnWorkerThread();
michael@0 824 return NotifyInternal(aCx, Closing);
michael@0 825 }
michael@0 826
michael@0 827 bool
michael@0 828 SuspendInternal(JSContext* aCx);
michael@0 829
michael@0 830 bool
michael@0 831 ResumeInternal(JSContext* aCx);
michael@0 832
michael@0 833 void
michael@0 834 TraceTimeouts(const TraceCallbacks& aCallbacks, void* aClosure) const;
michael@0 835
michael@0 836 bool
michael@0 837 ModifyBusyCountFromWorker(JSContext* aCx, bool aIncrease);
michael@0 838
michael@0 839 bool
michael@0 840 AddChildWorker(JSContext* aCx, ParentType* aChildWorker);
michael@0 841
michael@0 842 void
michael@0 843 RemoveChildWorker(JSContext* aCx, ParentType* aChildWorker);
michael@0 844
michael@0 845 bool
michael@0 846 AddFeature(JSContext* aCx, WorkerFeature* aFeature);
michael@0 847
michael@0 848 void
michael@0 849 RemoveFeature(JSContext* aCx, WorkerFeature* aFeature);
michael@0 850
michael@0 851 void
michael@0 852 NotifyFeatures(JSContext* aCx, Status aStatus);
michael@0 853
michael@0 854 bool
michael@0 855 HasActiveFeatures()
michael@0 856 {
michael@0 857 return !(mChildWorkers.IsEmpty() && mTimeouts.IsEmpty() &&
michael@0 858 mFeatures.IsEmpty());
michael@0 859 }
michael@0 860
michael@0 861 void
michael@0 862 PostMessageToParent(JSContext* aCx,
michael@0 863 JS::Handle<JS::Value> aMessage,
michael@0 864 const Optional<Sequence<JS::Value>>& aTransferable,
michael@0 865 ErrorResult& aRv)
michael@0 866 {
michael@0 867 PostMessageToParentInternal(aCx, aMessage, aTransferable, false, 0, aRv);
michael@0 868 }
michael@0 869
michael@0 870 void
michael@0 871 PostMessageToParentMessagePort(
michael@0 872 JSContext* aCx,
michael@0 873 uint64_t aMessagePortSerial,
michael@0 874 JS::Handle<JS::Value> aMessage,
michael@0 875 const Optional<Sequence<JS::Value>>& aTransferable,
michael@0 876 ErrorResult& aRv);
michael@0 877
michael@0 878 bool
michael@0 879 NotifyInternal(JSContext* aCx, Status aStatus);
michael@0 880
michael@0 881 void
michael@0 882 ReportError(JSContext* aCx, const char* aMessage, JSErrorReport* aReport);
michael@0 883
michael@0 884 int32_t
michael@0 885 SetTimeout(JSContext* aCx,
michael@0 886 Function* aHandler,
michael@0 887 const nsAString& aStringHandler,
michael@0 888 int32_t aTimeout,
michael@0 889 const Sequence<JS::Value>& aArguments,
michael@0 890 bool aIsInterval,
michael@0 891 ErrorResult& aRv);
michael@0 892
michael@0 893 void
michael@0 894 ClearTimeout(int32_t aId);
michael@0 895
michael@0 896 bool
michael@0 897 RunExpiredTimeouts(JSContext* aCx);
michael@0 898
michael@0 899 bool
michael@0 900 RescheduleTimeoutTimer(JSContext* aCx);
michael@0 901
michael@0 902 void
michael@0 903 CloseHandlerStarted()
michael@0 904 {
michael@0 905 AssertIsOnWorkerThread();
michael@0 906 mCloseHandlerStarted = true;
michael@0 907 }
michael@0 908
michael@0 909 void
michael@0 910 CloseHandlerFinished()
michael@0 911 {
michael@0 912 AssertIsOnWorkerThread();
michael@0 913 mCloseHandlerFinished = true;
michael@0 914 }
michael@0 915
michael@0 916 void
michael@0 917 UpdateRuntimeAndContextOptionsInternal(
michael@0 918 JSContext* aCx,
michael@0 919 const JS::RuntimeOptions& aRuntimeOptions,
michael@0 920 const JS::ContextOptions& aContentCxOptions,
michael@0 921 const JS::ContextOptions& aChromeCxOptions);
michael@0 922
michael@0 923 void
michael@0 924 UpdatePreferenceInternal(JSContext* aCx, WorkerPreference aPref, bool aValue);
michael@0 925
michael@0 926 void
michael@0 927 UpdateJSWorkerMemoryParameterInternal(JSContext* aCx, JSGCParamKey key, uint32_t aValue);
michael@0 928
michael@0 929 enum WorkerRanOrNot {
michael@0 930 WorkerNeverRan = 0,
michael@0 931 WorkerRan
michael@0 932 };
michael@0 933
michael@0 934 void
michael@0 935 ScheduleDeletion(WorkerRanOrNot aRanOrNot);
michael@0 936
michael@0 937 bool
michael@0 938 BlockAndCollectRuntimeStats(JS::RuntimeStats* aRtStats);
michael@0 939
michael@0 940 #ifdef JS_GC_ZEAL
michael@0 941 void
michael@0 942 UpdateGCZealInternal(JSContext* aCx, uint8_t aGCZeal, uint32_t aFrequency);
michael@0 943 #endif
michael@0 944
michael@0 945 void
michael@0 946 GarbageCollectInternal(JSContext* aCx, bool aShrinking,
michael@0 947 bool aCollectChildren);
michael@0 948
michael@0 949 void
michael@0 950 CycleCollectInternal(JSContext* aCx, bool aCollectChildren);
michael@0 951
michael@0 952 void
michael@0 953 OfflineStatusChangeEventInternal(JSContext* aCx, bool aIsOffline);
michael@0 954
michael@0 955 JSContext*
michael@0 956 GetJSContext() const
michael@0 957 {
michael@0 958 AssertIsOnWorkerThread();
michael@0 959 return mJSContext;
michael@0 960 }
michael@0 961
michael@0 962 WorkerGlobalScope*
michael@0 963 GlobalScope() const
michael@0 964 {
michael@0 965 AssertIsOnWorkerThread();
michael@0 966 return mScope;
michael@0 967 }
michael@0 968
michael@0 969 void
michael@0 970 SetThread(nsIThread* aThread);
michael@0 971
michael@0 972 void
michael@0 973 AssertIsOnWorkerThread() const
michael@0 974 #ifdef DEBUG
michael@0 975 ;
michael@0 976 #else
michael@0 977 { }
michael@0 978 #endif
michael@0 979
michael@0 980 WorkerCrossThreadDispatcher*
michael@0 981 GetCrossThreadDispatcher();
michael@0 982
michael@0 983 // This may block!
michael@0 984 void
michael@0 985 BeginCTypesCall();
michael@0 986
michael@0 987 // This may block!
michael@0 988 void
michael@0 989 EndCTypesCall();
michael@0 990
michael@0 991 void
michael@0 992 BeginCTypesCallback()
michael@0 993 {
michael@0 994 // If a callback is beginning then we need to do the exact same thing as
michael@0 995 // when a ctypes call ends.
michael@0 996 EndCTypesCall();
michael@0 997 }
michael@0 998
michael@0 999 void
michael@0 1000 EndCTypesCallback()
michael@0 1001 {
michael@0 1002 // If a callback is ending then we need to do the exact same thing as
michael@0 1003 // when a ctypes call begins.
michael@0 1004 BeginCTypesCall();
michael@0 1005 }
michael@0 1006
michael@0 1007 bool
michael@0 1008 ConnectMessagePort(JSContext* aCx, uint64_t aMessagePortSerial);
michael@0 1009
michael@0 1010 void
michael@0 1011 DisconnectMessagePort(uint64_t aMessagePortSerial);
michael@0 1012
michael@0 1013 MessagePort*
michael@0 1014 GetMessagePort(uint64_t aMessagePortSerial);
michael@0 1015
michael@0 1016 JSObject*
michael@0 1017 CreateGlobalScope(JSContext* aCx);
michael@0 1018
michael@0 1019 bool
michael@0 1020 RegisterBindings(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
michael@0 1021
michael@0 1022 bool
michael@0 1023 DumpEnabled() const
michael@0 1024 {
michael@0 1025 AssertIsOnWorkerThread();
michael@0 1026 return mPreferences[WORKERPREF_DUMP];
michael@0 1027 }
michael@0 1028
michael@0 1029 bool
michael@0 1030 OnLine() const
michael@0 1031 {
michael@0 1032 AssertIsOnWorkerThread();
michael@0 1033 return mOnLine;
michael@0 1034 }
michael@0 1035
michael@0 1036 void
michael@0 1037 StopSyncLoop(nsIEventTarget* aSyncLoopTarget, bool aResult);
michael@0 1038
michael@0 1039 bool
michael@0 1040 AllPendingRunnablesShouldBeCanceled() const
michael@0 1041 {
michael@0 1042 return mCancelAllPendingRunnables;
michael@0 1043 }
michael@0 1044
michael@0 1045 void
michael@0 1046 OnProcessNextEvent(uint32_t aRecursionDepth);
michael@0 1047
michael@0 1048 void
michael@0 1049 AfterProcessNextEvent(uint32_t aRecursionDepth);
michael@0 1050
michael@0 1051 void
michael@0 1052 AssertValidSyncLoop(nsIEventTarget* aSyncLoopTarget)
michael@0 1053 #ifdef DEBUG
michael@0 1054 ;
michael@0 1055 #else
michael@0 1056 { }
michael@0 1057 #endif
michael@0 1058
michael@0 1059 private:
michael@0 1060 WorkerPrivate(JSContext* aCx, WorkerPrivate* aParent,
michael@0 1061 const nsAString& aScriptURL, bool aIsChromeWorker,
michael@0 1062 WorkerType aWorkerType, const nsACString& aSharedWorkerName,
michael@0 1063 LoadInfo& aLoadInfo);
michael@0 1064
michael@0 1065 void
michael@0 1066 ClearMainEventQueue(WorkerRanOrNot aRanOrNot);
michael@0 1067
michael@0 1068 bool
michael@0 1069 MayContinueRunning()
michael@0 1070 {
michael@0 1071 AssertIsOnWorkerThread();
michael@0 1072
michael@0 1073 Status status;
michael@0 1074 {
michael@0 1075 MutexAutoLock lock(mMutex);
michael@0 1076 status = mStatus;
michael@0 1077 }
michael@0 1078
michael@0 1079 if (status >= Killing) {
michael@0 1080 return false;
michael@0 1081 }
michael@0 1082 if (status >= Running) {
michael@0 1083 return mKillTime.IsNull() || RemainingRunTimeMS() > 0;
michael@0 1084 }
michael@0 1085 return true;
michael@0 1086 }
michael@0 1087
michael@0 1088 uint32_t
michael@0 1089 RemainingRunTimeMS() const;
michael@0 1090
michael@0 1091 void
michael@0 1092 CancelAllTimeouts(JSContext* aCx);
michael@0 1093
michael@0 1094 bool
michael@0 1095 ScheduleKillCloseEventRunnable(JSContext* aCx);
michael@0 1096
michael@0 1097 bool
michael@0 1098 ProcessAllControlRunnables()
michael@0 1099 {
michael@0 1100 MutexAutoLock lock(mMutex);
michael@0 1101 return ProcessAllControlRunnablesLocked();
michael@0 1102 }
michael@0 1103
michael@0 1104 bool
michael@0 1105 ProcessAllControlRunnablesLocked();
michael@0 1106
michael@0 1107 void
michael@0 1108 EnableMemoryReporter();
michael@0 1109
michael@0 1110 void
michael@0 1111 DisableMemoryReporter();
michael@0 1112
michael@0 1113 void
michael@0 1114 WaitForWorkerEvents(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT);
michael@0 1115
michael@0 1116 void
michael@0 1117 PostMessageToParentInternal(JSContext* aCx,
michael@0 1118 JS::Handle<JS::Value> aMessage,
michael@0 1119 const Optional<Sequence<JS::Value>>& aTransferable,
michael@0 1120 bool aToMessagePort,
michael@0 1121 uint64_t aMessagePortSerial,
michael@0 1122 ErrorResult& aRv);
michael@0 1123
michael@0 1124 void
michael@0 1125 GetAllPreferences(bool aPreferences[WORKERPREF_COUNT]) const
michael@0 1126 {
michael@0 1127 AssertIsOnWorkerThread();
michael@0 1128 memcpy(aPreferences, mPreferences, WORKERPREF_COUNT * sizeof(bool));
michael@0 1129 }
michael@0 1130
michael@0 1131 already_AddRefed<nsIEventTarget>
michael@0 1132 CreateNewSyncLoop();
michael@0 1133
michael@0 1134 bool
michael@0 1135 RunCurrentSyncLoop();
michael@0 1136
michael@0 1137 bool
michael@0 1138 DestroySyncLoop(uint32_t aLoopIndex, nsIThreadInternal* aThread = nullptr);
michael@0 1139
michael@0 1140 void
michael@0 1141 InitializeGCTimers();
michael@0 1142
michael@0 1143 void
michael@0 1144 SetGCTimerMode(GCTimerMode aMode);
michael@0 1145
michael@0 1146 void
michael@0 1147 ShutdownGCTimers();
michael@0 1148 };
michael@0 1149
michael@0 1150 // This class is only used to trick the DOM bindings. We never create
michael@0 1151 // instances of it, and static_casting to it is fine since it doesn't add
michael@0 1152 // anything to WorkerPrivate.
michael@0 1153 class ChromeWorkerPrivate : public WorkerPrivate
michael@0 1154 {
michael@0 1155 public:
michael@0 1156 static already_AddRefed<ChromeWorkerPrivate>
michael@0 1157 Constructor(const GlobalObject& aGlobal, const nsAString& aScriptURL,
michael@0 1158 ErrorResult& rv);
michael@0 1159
michael@0 1160 static bool
michael@0 1161 WorkerAvailable(JSContext* /* unused */, JSObject* /* unused */);
michael@0 1162
michael@0 1163 private:
michael@0 1164 ChromeWorkerPrivate() MOZ_DELETE;
michael@0 1165 ChromeWorkerPrivate(const ChromeWorkerPrivate& aRHS) MOZ_DELETE;
michael@0 1166 ChromeWorkerPrivate& operator =(const ChromeWorkerPrivate& aRHS) MOZ_DELETE;
michael@0 1167 };
michael@0 1168
michael@0 1169 WorkerPrivate*
michael@0 1170 GetWorkerPrivateFromContext(JSContext* aCx);
michael@0 1171
michael@0 1172 WorkerPrivate*
michael@0 1173 GetCurrentThreadWorkerPrivate();
michael@0 1174
michael@0 1175 bool
michael@0 1176 IsCurrentThreadRunningChromeWorker();
michael@0 1177
michael@0 1178 JSContext*
michael@0 1179 GetCurrentThreadJSContext();
michael@0 1180
michael@0 1181 enum WorkerStructuredDataType
michael@0 1182 {
michael@0 1183 DOMWORKER_SCTAG_FILE = SCTAG_DOM_MAX,
michael@0 1184 DOMWORKER_SCTAG_BLOB,
michael@0 1185
michael@0 1186 DOMWORKER_SCTAG_END
michael@0 1187 };
michael@0 1188
michael@0 1189 JSStructuredCloneCallbacks*
michael@0 1190 WorkerStructuredCloneCallbacks(bool aMainRuntime);
michael@0 1191
michael@0 1192 JSStructuredCloneCallbacks*
michael@0 1193 ChromeWorkerStructuredCloneCallbacks(bool aMainRuntime);
michael@0 1194
michael@0 1195 class AutoSyncLoopHolder
michael@0 1196 {
michael@0 1197 WorkerPrivate* mWorkerPrivate;
michael@0 1198 nsCOMPtr<nsIEventTarget> mTarget;
michael@0 1199 uint32_t mIndex;
michael@0 1200
michael@0 1201 public:
michael@0 1202 AutoSyncLoopHolder(WorkerPrivate* aWorkerPrivate)
michael@0 1203 : mWorkerPrivate(aWorkerPrivate)
michael@0 1204 , mTarget(aWorkerPrivate->CreateNewSyncLoop())
michael@0 1205 , mIndex(aWorkerPrivate->mSyncLoopStack.Length() - 1)
michael@0 1206 {
michael@0 1207 aWorkerPrivate->AssertIsOnWorkerThread();
michael@0 1208 }
michael@0 1209
michael@0 1210 ~AutoSyncLoopHolder()
michael@0 1211 {
michael@0 1212 if (mWorkerPrivate) {
michael@0 1213 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 1214 mWorkerPrivate->StopSyncLoop(mTarget, false);
michael@0 1215 mWorkerPrivate->DestroySyncLoop(mIndex);
michael@0 1216 }
michael@0 1217 }
michael@0 1218
michael@0 1219 bool
michael@0 1220 Run()
michael@0 1221 {
michael@0 1222 WorkerPrivate* workerPrivate = mWorkerPrivate;
michael@0 1223 mWorkerPrivate = nullptr;
michael@0 1224
michael@0 1225 workerPrivate->AssertIsOnWorkerThread();
michael@0 1226
michael@0 1227 return workerPrivate->RunCurrentSyncLoop();
michael@0 1228 }
michael@0 1229
michael@0 1230 nsIEventTarget*
michael@0 1231 EventTarget() const
michael@0 1232 {
michael@0 1233 return mTarget;
michael@0 1234 }
michael@0 1235 };
michael@0 1236
michael@0 1237 END_WORKERS_NAMESPACE
michael@0 1238
michael@0 1239 #endif /* mozilla_dom_workers_workerprivate_h__ */

mercurial