summaryrefslogtreecommitdiffstats
path: root/WebCore/page/Geolocation.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2009-09-02 16:17:41 +0100
committerSteve Block <steveblock@google.com>2009-09-04 15:14:07 +0100
commite27fedc48d78b1c1b6e656fe42d64efd60056464 (patch)
tree371d1c66e1c2bd4b03fa706cb75c29e158a26b2e /WebCore/page/Geolocation.cpp
parent4abe833d66929ee0f0363cf63dfe35ffe3d5a0a2 (diff)
downloadexternal_webkit-e27fedc48d78b1c1b6e656fe42d64efd60056464.zip
external_webkit-e27fedc48d78b1c1b6e656fe42d64efd60056464.tar.gz
external_webkit-e27fedc48d78b1c1b6e656fe42d64efd60056464.tar.bz2
Fix Geolocation to correctly handle reentrant calls from callbacks.
This fixes http://b/issue?id=2094823.
Diffstat (limited to 'WebCore/page/Geolocation.cpp')
-rw-r--r--WebCore/page/Geolocation.cpp58
1 files changed, 21 insertions, 37 deletions
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index a419b0b..359c125 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -209,22 +209,6 @@ void Geolocation::sendError(Vector<RefPtr<GeoNotifier> >& notifiers, PositionErr
}
}
-void Geolocation::sendErrorToOneShots(PositionError* error)
-{
- Vector<RefPtr<GeoNotifier> > copy;
- copyToVector(m_oneShots, copy);
-
- sendError(copy, error);
-}
-
-void Geolocation::sendErrorToWatchers(PositionError* error)
-{
- Vector<RefPtr<GeoNotifier> > copy;
- copyValuesToVector(m_watchers, copy);
-
- sendError(copy, error);
-}
-
void Geolocation::sendPosition(Vector<RefPtr<GeoNotifier> >& notifiers, Geoposition* position)
{
Vector<RefPtr<GeoNotifier> >::const_iterator end = notifiers.end();
@@ -237,22 +221,6 @@ void Geolocation::sendPosition(Vector<RefPtr<GeoNotifier> >& notifiers, Geoposit
}
}
-void Geolocation::sendPositionToOneShots(Geoposition* position)
-{
- Vector<RefPtr<GeoNotifier> > copy;
- copyToVector(m_oneShots, copy);
-
- sendPosition(copy, position);
-}
-
-void Geolocation::sendPositionToWatchers(Geoposition* position)
-{
- Vector<RefPtr<GeoNotifier> > copy;
- copyValuesToVector(m_watchers, copy);
-
- sendPosition(copy, position);
-}
-
void Geolocation::stopTimer(Vector<RefPtr<GeoNotifier> >& notifiers)
{
Vector<RefPtr<GeoNotifier> >::const_iterator end = notifiers.end();
@@ -287,14 +255,22 @@ void Geolocation::stopTimers()
void Geolocation::handleError(PositionError* error)
{
ASSERT(error);
-
- sendErrorToOneShots(error);
- sendErrorToWatchers(error);
+ Vector<RefPtr<GeoNotifier> > oneShotsCopy;
+ copyToVector(m_oneShots, oneShotsCopy);
+
+ Vector<RefPtr<GeoNotifier> > watchersCopy;
+ copyValuesToVector(m_watchers, watchersCopy);
+
+ // Clear the lists before we make the callbacks, to avoid clearing notifiers
+ // added by calls to Geolocation methods from the callbacks.
m_oneShots.clear();
if (error->isFatal())
m_watchers.clear();
+ sendError(oneShotsCopy, error);
+ sendError(watchersCopy, error);
+
if (!hasListeners())
m_service->stopUpdating();
}
@@ -341,11 +317,19 @@ void Geolocation::makeSuccessCallbacks()
ASSERT(m_service->lastPosition());
ASSERT(isAllowed());
- sendPositionToOneShots(m_service->lastPosition());
- sendPositionToWatchers(m_service->lastPosition());
+ Vector<RefPtr<GeoNotifier> > oneShotsCopy;
+ copyToVector(m_oneShots, oneShotsCopy);
+
+ Vector<RefPtr<GeoNotifier> > watchersCopy;
+ copyValuesToVector(m_watchers, watchersCopy);
+ // Clear the lists before we make the callbacks, to avoid clearing notifiers
+ // added by calls to Geolocation methods from the callbacks.
m_oneShots.clear();
+ sendPosition(oneShotsCopy, m_service->lastPosition());
+ sendPosition(watchersCopy, m_service->lastPosition());
+
if (!hasListeners())
m_service->stopUpdating();
}