WebWorkerNote: Difference between revisions

Jump to navigation Jump to search
Line 80: Line 80:
   return worker.forget();
   return worker.forget();
}
}
NS_IMETHODIMP
WorkerRunnable::Run()
{
  bool targetIsWorkerThread = mBehavior == WorkerThreadModifyBusyCount ||
                              mBehavior == WorkerThreadUnchangedBusyCount;
#ifdef DEBUG
  MOZ_ASSERT_IF(mCallingCancelWithinRun, targetIsWorkerThread);
  if (targetIsWorkerThread) {
    mWorkerPrivate->AssertIsOnWorkerThread();
  }
  else {
    MOZ_ASSERT(mBehavior == ParentThreadUnchangedBusyCount);
    mWorkerPrivate->AssertIsOnParentThread();
  }
#endif
  if (IsCanceled() && !mCallingCancelWithinRun) {
    return NS_OK;
  }
  if (targetIsWorkerThread &&
      mWorkerPrivate->AllPendingRunnablesShouldBeCanceled() &&
      !IsCanceled() && !mCallingCancelWithinRun) {
    // Prevent recursion.
    mCallingCancelWithinRun = true;
    Cancel();
    MOZ_ASSERT(mCallingCancelWithinRun);
    mCallingCancelWithinRun = false;
    MOZ_ASSERT(IsCanceled(), "Subclass Cancel() didn't set IsCanceled()!");
    return NS_OK;
}
  // Track down the appropriate global to use for the AutoJSAPI/AutoEntryScript.
  nsCOMPtr<nsIGlobalObject> globalObject;
  bool isMainThread = !targetIsWorkerThread && !mWorkerPrivate->GetParent();
  MOZ_ASSERT(isMainThread == NS_IsMainThread());
  nsRefPtr<WorkerPrivate> kungFuDeathGrip;
  if (targetIsWorkerThread) {
    globalObject = mWorkerPrivate->GlobalScope();
  }
  else {
    kungFuDeathGrip = mWorkerPrivate;
    if (isMainThread) {
      globalObject = static_cast<nsGlobalWindow*>(mWorkerPrivate->GetWindow());
    } else {
      globalObject = mWorkerPrivate->GetParent()->GlobalScope();
    }
  }
  // We might run script as part of WorkerRun, so we need an AutoEntryScript.
  // This is part of the HTML spec for workers at:
  // http://www.whatwg.org/specs/web-apps/current-work/#run-a-worker
  // If we don't have a globalObject we have to use an AutoJSAPI instead, but
  // this is OK as we won't be running script in these circumstances.
  // It's important that aes is declared after jsapi, because if WorkerRun
  // creates a global then we construct aes before PostRun and we need them to
  // be destroyed in the correct order.
  mozilla::dom::AutoJSAPI jsapi;
  Maybe<mozilla::dom::AutoEntryScript> aes;
  JSContext* cx;
  if (globalObject) {
    aes.emplace(globalObject, isMainThread, isMainThread ? nullptr :
                                            GetCurrentThreadJSContext());
    cx = aes->cx();
  } else {
    jsapi.Init();
    cx = jsapi.cx();
  }
  // If we're not on the worker thread we'll either be in our parent's
  // compartment or the null compartment, so we need to enter our own.
  Maybe<JSAutoCompartment> ac;
  if (!targetIsWorkerThread && mWorkerPrivate->GetWrapper()) {
    ac.emplace(cx, mWorkerPrivate->GetWrapper());
  }
  bool result = WorkerRun(cx, mWorkerPrivate);
  // In the case of CompileScriptRunnnable, WorkerRun above can cause us to
  // lazily create a global, so we construct aes here before calling PostRun.
  if (targetIsWorkerThread && !aes && mWorkerPrivate->GlobalScope()) {
    aes.emplace(mWorkerPrivate->GlobalScope(), false, GetCurrentThreadJSContext());
    cx = aes->cx();
  }
  PostRun(cx, mWorkerPrivate, result);
  return result ? NS_OK : NS_ERROR_FAILURE;
}
class CompileScriptRunnable MOZ_FINAL : public WorkerRunnable
{
public:
  explicit CompileScriptRunnable(WorkerPrivate* aWorkerPrivate)
  : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
  { }
private:
  virtual bool
  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) MOZ_OVERRIDE
  {
    JS::Rooted<JSObject*> global(aCx,
      aWorkerPrivate->CreateGlobalScope(aCx));
    if (!global) {
      NS_WARNING("Failed to make global!");
      return false;
    }
    JSAutoCompartment ac(aCx, global);
    bool result = scriptloader::LoadWorkerScript(aCx);
    if (result) {
      aWorkerPrivate->SetWorkerScriptExecutedSuccessfully();
    }
    return result;
  }
};


</source>
</source>


=Shared Worker=
=Shared Worker=
Confirmed users
770

edits

Navigation menu