dom/smil/nsSMILInstanceTime.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; 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
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsSMILInstanceTime.h"
     7 #include "nsSMILInterval.h"
     8 #include "nsSMILTimeValueSpec.h"
     9 #include "mozilla/AutoRestore.h"
    11 //----------------------------------------------------------------------
    12 // Implementation
    14 nsSMILInstanceTime::nsSMILInstanceTime(const nsSMILTimeValue& aTime,
    15                                        nsSMILInstanceTimeSource aSource,
    16                                        nsSMILTimeValueSpec* aCreator,
    17                                        nsSMILInterval* aBaseInterval)
    18   : mTime(aTime),
    19     mFlags(0),
    20     mVisited(false),
    21     mFixedEndpointRefCnt(0),
    22     mSerial(0),
    23     mCreator(aCreator),
    24     mBaseInterval(nullptr) // This will get set to aBaseInterval in a call to
    25                           // SetBaseInterval() at end of constructor
    26 {
    27   switch (aSource) {
    28     case SOURCE_NONE:
    29       // No special flags
    30       break;
    32     case SOURCE_DOM:
    33       mFlags = kDynamic | kFromDOM;
    34       break;
    36     case SOURCE_SYNCBASE:
    37       mFlags = kMayUpdate;
    38       break;
    40     case SOURCE_EVENT:
    41       mFlags = kDynamic;
    42       break;
    43   }
    45   SetBaseInterval(aBaseInterval);
    46 }
    48 nsSMILInstanceTime::~nsSMILInstanceTime()
    49 {
    50   NS_ABORT_IF_FALSE(!mBaseInterval,
    51       "Destroying instance time without first calling Unlink()");
    52   NS_ABORT_IF_FALSE(mFixedEndpointRefCnt == 0,
    53       "Destroying instance time that is still used as the fixed endpoint of an "
    54       "interval");
    55 }
    57 void
    58 nsSMILInstanceTime::Unlink()
    59 {
    60   nsRefPtr<nsSMILInstanceTime> deathGrip(this);
    61   if (mBaseInterval) {
    62     mBaseInterval->RemoveDependentTime(*this);
    63     mBaseInterval = nullptr;
    64   }
    65   mCreator = nullptr;
    66 }
    68 void
    69 nsSMILInstanceTime::HandleChangedInterval(
    70     const nsSMILTimeContainer* aSrcContainer,
    71     bool aBeginObjectChanged,
    72     bool aEndObjectChanged)
    73 {
    74   // It's possible a sequence of notifications might cause our base interval to
    75   // be updated and then deleted. Furthermore, the delete might happen whilst
    76   // we're still in the queue to be notified of the change. In any case, if we
    77   // don't have a base interval, just ignore the change.
    78   if (!mBaseInterval)
    79     return;
    81   NS_ABORT_IF_FALSE(mCreator, "Base interval is set but creator is not.");
    83   if (mVisited) {
    84     // Break the cycle here
    85     Unlink();
    86     return;
    87   }
    89   bool objectChanged = mCreator->DependsOnBegin() ? aBeginObjectChanged :
    90                                                       aEndObjectChanged;
    92   mozilla::AutoRestore<bool> setVisited(mVisited);
    93   mVisited = true;
    95   nsRefPtr<nsSMILInstanceTime> deathGrip(this);
    96   mCreator->HandleChangedInstanceTime(*GetBaseTime(), aSrcContainer, *this,
    97                                       objectChanged);
    98 }
   100 void
   101 nsSMILInstanceTime::HandleDeletedInterval()
   102 {
   103   NS_ABORT_IF_FALSE(mBaseInterval,
   104       "Got call to HandleDeletedInterval on an independent instance time");
   105   NS_ABORT_IF_FALSE(mCreator, "Base interval is set but creator is not");
   107   mBaseInterval = nullptr;
   108   mFlags &= ~kMayUpdate; // Can't update without a base interval
   110   nsRefPtr<nsSMILInstanceTime> deathGrip(this);
   111   mCreator->HandleDeletedInstanceTime(*this);
   112   mCreator = nullptr;
   113 }
   115 void
   116 nsSMILInstanceTime::HandleFilteredInterval()
   117 {
   118   NS_ABORT_IF_FALSE(mBaseInterval,
   119       "Got call to HandleFilteredInterval on an independent instance time");
   121   mBaseInterval = nullptr;
   122   mFlags &= ~kMayUpdate; // Can't update without a base interval
   123   mCreator = nullptr;
   124 }
   126 bool
   127 nsSMILInstanceTime::ShouldPreserve() const
   128 {
   129   return mFixedEndpointRefCnt > 0 || (mFlags & kWasDynamicEndpoint);
   130 }
   132 void
   133 nsSMILInstanceTime::UnmarkShouldPreserve()
   134 {
   135   mFlags &= ~kWasDynamicEndpoint;
   136 }
   138 void
   139 nsSMILInstanceTime::AddRefFixedEndpoint()
   140 {
   141   NS_ABORT_IF_FALSE(mFixedEndpointRefCnt < UINT16_MAX,
   142       "Fixed endpoint reference count upper limit reached");
   143   ++mFixedEndpointRefCnt;
   144   mFlags &= ~kMayUpdate; // Once fixed, always fixed
   145 }
   147 void
   148 nsSMILInstanceTime::ReleaseFixedEndpoint()
   149 {
   150   NS_ABORT_IF_FALSE(mFixedEndpointRefCnt > 0, "Duplicate release");
   151   --mFixedEndpointRefCnt;
   152   if (mFixedEndpointRefCnt == 0 && IsDynamic()) {
   153     mFlags |= kWasDynamicEndpoint;
   154   }
   155 }
   157 bool
   158 nsSMILInstanceTime::IsDependentOn(const nsSMILInstanceTime& aOther) const
   159 {
   160   if (mVisited)
   161     return false;
   163   const nsSMILInstanceTime* myBaseTime = GetBaseTime();
   164   if (!myBaseTime)
   165     return false;
   167   if (myBaseTime == &aOther)
   168     return true;
   170   mozilla::AutoRestore<bool> setVisited(mVisited);
   171   mVisited = true;
   172   return myBaseTime->IsDependentOn(aOther);
   173 }
   175 const nsSMILInstanceTime*
   176 nsSMILInstanceTime::GetBaseTime() const
   177 {
   178   if (!mBaseInterval) {
   179     return nullptr;
   180   }
   182   NS_ABORT_IF_FALSE(mCreator, "Base interval is set but there is no creator.");
   183   if (!mCreator) {
   184     return nullptr;
   185   }
   187   return mCreator->DependsOnBegin() ? mBaseInterval->Begin() :
   188                                       mBaseInterval->End();
   189 }
   191 void
   192 nsSMILInstanceTime::SetBaseInterval(nsSMILInterval* aBaseInterval)
   193 {
   194   NS_ABORT_IF_FALSE(!mBaseInterval,
   195       "Attempting to reassociate an instance time with a different interval.");
   197   if (aBaseInterval) {
   198     NS_ABORT_IF_FALSE(mCreator,
   199         "Attempting to create a dependent instance time without reference "
   200         "to the creating nsSMILTimeValueSpec object.");
   201     if (!mCreator)
   202       return;
   204     aBaseInterval->AddDependentTime(*this);
   205   }
   207   mBaseInterval = aBaseInterval;
   208 }

mercurial