Bug 937129 - Fix some concurrency issues in APZCTM::HandleOverscroll. r=kats

This commit is contained in:
Botond Ballo 2013-11-11 12:06:33 -05:00
Родитель db75b2138e
Коммит acc75156c8
3 изменённых файлов: 20 добавлений и 5 удалений

Просмотреть файл

@ -584,7 +584,15 @@ APZCTreeManager::ClearTree()
void
APZCTreeManager::HandleOverscroll(AsyncPanZoomController* aChild, ScreenPoint aStartPoint, ScreenPoint aEndPoint)
{
AsyncPanZoomController* parent = aChild->GetParent();
nsRefPtr<AsyncPanZoomController> parent;
{
// The tree lock needs to be held while navigating from an apzc to its
// parent. We don't hold it any longer though because GetInputTransforms()
// does its own locking, and AttemptScroll() can call HandleOverscroll()
// recursively.
MonitorAutoLock lock(mTreeLock);
parent = aChild->GetParent();
}
if (parent == nullptr)
return;
@ -597,7 +605,7 @@ APZCTreeManager::HandleOverscroll(AsyncPanZoomController* aChild, ScreenPoint aS
ApplyTransform(&aEndPoint, transformToApzc.Inverse());
// Convert start and end points to parent's transformed screen coordinates.
GetInputTransforms(parent, transformToApzc, transformToGecko);
GetInputTransforms(parent.get(), transformToApzc, transformToGecko);
ApplyTransform(&aStartPoint, transformToApzc);
ApplyTransform(&aEndPoint, transformToApzc);

Просмотреть файл

@ -862,8 +862,14 @@ void AsyncPanZoomController::AttemptScroll(const ScreenPoint& aStartPoint,
}
if (fabs(overscroll.x) > EPSILON || fabs(overscroll.y) > EPSILON) {
// "+ overscroll" rather than "- overscroll" for the same reason as above.
mTreeManager->HandleOverscroll(this, aEndPoint + overscroll, aEndPoint);
// Make a local copy of the tree manager pointer and check if it's not
// null before calling HandleOverscroll(). This is necessary because
// Destroy(), which nulls out mTreeManager, could be called concurrently.
APZCTreeManager* treeManagerLocal = mTreeManager;
if (treeManagerLocal) {
// "+ overscroll" rather than "- overscroll" for the same reason as above.
treeManagerLocal->HandleOverscroll(this, aEndPoint + overscroll, aEndPoint);
}
}
}

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/Monitor.h"
#include "mozilla/ReentrantMonitor.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Atomics.h"
#include "InputData.h"
#include "Axis.h"
#include "TaskThrottler.h"
@ -648,7 +649,7 @@ private:
// live on the main thread, we can't use the cycle collector with them.
// The APZCTreeManager owns the lifetime of the APZCs, so nulling this
// pointer out in Destroy() will prevent accessing deleted memory.
APZCTreeManager* mTreeManager;
Atomic<APZCTreeManager*> mTreeManager;
nsRefPtr<AsyncPanZoomController> mLastChild;
nsRefPtr<AsyncPanZoomController> mPrevSibling;