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 : #include "mozilla/dom/cache/CacheWorkerHolder.h"
8 :
9 : #include "mozilla/dom/cache/ActorChild.h"
10 : #include "WorkerPrivate.h"
11 :
12 : namespace mozilla {
13 : namespace dom {
14 : namespace cache {
15 :
16 : using mozilla::dom::workers::Terminating;
17 : using mozilla::dom::workers::Status;
18 : using mozilla::dom::workers::WorkerPrivate;
19 :
20 : // static
21 : already_AddRefed<CacheWorkerHolder>
22 0 : CacheWorkerHolder::Create(WorkerPrivate* aWorkerPrivate, Behavior aBehavior)
23 : {
24 0 : MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate);
25 :
26 0 : RefPtr<CacheWorkerHolder> workerHolder = new CacheWorkerHolder(aBehavior);
27 0 : if (NS_WARN_IF(!workerHolder->HoldWorker(aWorkerPrivate, Terminating))) {
28 0 : return nullptr;
29 : }
30 :
31 0 : return workerHolder.forget();
32 : }
33 :
34 : // static
35 : already_AddRefed<CacheWorkerHolder>
36 0 : CacheWorkerHolder::PreferBehavior(CacheWorkerHolder* aCurrentHolder,
37 : Behavior aBehavior)
38 : {
39 0 : if (!aCurrentHolder) {
40 0 : return nullptr;
41 : }
42 :
43 0 : RefPtr<CacheWorkerHolder> orig = aCurrentHolder;
44 0 : if (orig->GetBehavior() == aBehavior) {
45 0 : return orig.forget();
46 : }
47 :
48 0 : RefPtr<CacheWorkerHolder> replace = Create(orig->mWorkerPrivate, aBehavior);
49 0 : if (!replace) {
50 0 : return orig.forget();
51 : }
52 :
53 0 : return replace.forget();
54 : }
55 :
56 : void
57 0 : CacheWorkerHolder::AddActor(ActorChild* aActor)
58 : {
59 0 : NS_ASSERT_OWNINGTHREAD(CacheWorkerHolder);
60 0 : MOZ_DIAGNOSTIC_ASSERT(aActor);
61 0 : MOZ_ASSERT(!mActorList.Contains(aActor));
62 :
63 0 : mActorList.AppendElement(aActor);
64 :
65 : // Allow an actor to be added after we've entered the Notifying case. We
66 : // can't stop the actor creation from racing with out destruction of the
67 : // other actors and we need to wait for this extra one to close as well.
68 : // Signal it should destroy itself right away.
69 0 : if (mNotified) {
70 0 : aActor->StartDestroy();
71 : }
72 0 : }
73 :
74 : void
75 0 : CacheWorkerHolder::RemoveActor(ActorChild* aActor)
76 : {
77 0 : NS_ASSERT_OWNINGTHREAD(CacheWorkerHolder);
78 0 : MOZ_DIAGNOSTIC_ASSERT(aActor);
79 :
80 : #if defined(RELEASE_OR_BETA)
81 : mActorList.RemoveElement(aActor);
82 : #else
83 0 : MOZ_DIAGNOSTIC_ASSERT(mActorList.RemoveElement(aActor));
84 : #endif
85 :
86 0 : MOZ_ASSERT(!mActorList.Contains(aActor));
87 0 : }
88 :
89 : bool
90 0 : CacheWorkerHolder::Notified() const
91 : {
92 0 : return mNotified;
93 : }
94 :
95 : bool
96 0 : CacheWorkerHolder::Notify(Status aStatus)
97 : {
98 0 : NS_ASSERT_OWNINGTHREAD(CacheWorkerHolder);
99 :
100 : // When the service worker thread is stopped we will get Terminating,
101 : // but nothing higher than that. We must shut things down at Terminating.
102 0 : if (aStatus < Terminating || mNotified) {
103 0 : return true;
104 : }
105 :
106 0 : mNotified = true;
107 :
108 : // Start the asynchronous destruction of our actors. These will call back
109 : // into RemoveActor() once the actor is destroyed.
110 0 : for (uint32_t i = 0; i < mActorList.Length(); ++i) {
111 0 : MOZ_DIAGNOSTIC_ASSERT(mActorList[i]);
112 0 : mActorList[i]->StartDestroy();
113 : }
114 :
115 0 : return true;
116 : }
117 :
118 0 : CacheWorkerHolder::CacheWorkerHolder(Behavior aBehavior)
119 : : WorkerHolder(aBehavior)
120 0 : , mNotified(false)
121 : {
122 0 : }
123 :
124 0 : CacheWorkerHolder::~CacheWorkerHolder()
125 : {
126 0 : NS_ASSERT_OWNINGTHREAD(CacheWorkerHolder);
127 0 : MOZ_DIAGNOSTIC_ASSERT(mActorList.IsEmpty());
128 0 : }
129 :
130 : } // namespace cache
131 : } // namespace dom
132 : } // namespace mozilla
|