[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-10851-g50815da
steveblock at google.com
steveblock at google.com
Wed Dec 22 18:49:34 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit dc3311273bf710e56a0eb74502cfa1833df689bd
Author: steveblock at google.com <steveblock at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Dec 20 18:41:41 2010 +0000
2010-12-20 Steve Block <steveblock at google.com>
Reviewed by Jeremy Orlow.
GeolocationPositionCache should do database access on background thread
https://bugs.webkit.org/show_bug.cgi?id=50825
Covered by existing Geolocation tests.
* page/Coordinates.h:
(WebCore::Coordinates::threadSafeCopy):
* page/GeolocationPositionCache.cpp:
(WebCore::GeolocationPositionCache::GeolocationPositionCache):
(WebCore::GeolocationPositionCache::addUser):
(WebCore::GeolocationPositionCache::removeUser):
(WebCore::GeolocationPositionCache::setDatabasePath):
(WebCore::GeolocationPositionCache::setCachedPosition):
(WebCore::GeolocationPositionCache::cachedPosition):
(WebCore::GeolocationPositionCache::startBackgroundThread):
(WebCore::GeolocationPositionCache::threadEntryPoint):
(WebCore::GeolocationPositionCache::threadEntryPointImpl):
(WebCore::GeolocationPositionCache::triggerReadFromDatabase):
(WebCore::GeolocationPositionCache::readFromDatabase):
(WebCore::GeolocationPositionCache::readFromDatabaseImpl):
(WebCore::GeolocationPositionCache::triggerWriteToDatabase):
(WebCore::GeolocationPositionCache::writeToDatabase):
(WebCore::GeolocationPositionCache::writeToDatabaseImpl):
* page/GeolocationPositionCache.h:
* page/Geoposition.h:
(WebCore::Geoposition::threadSafeCopy):
(WebCore::Geoposition::Geoposition):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@74354 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 4589ca5..56aa211 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,35 @@
+2010-12-20 Steve Block <steveblock at google.com>
+
+ Reviewed by Jeremy Orlow.
+
+ GeolocationPositionCache should do database access on background thread
+ https://bugs.webkit.org/show_bug.cgi?id=50825
+
+ Covered by existing Geolocation tests.
+
+ * page/Coordinates.h:
+ (WebCore::Coordinates::threadSafeCopy):
+ * page/GeolocationPositionCache.cpp:
+ (WebCore::GeolocationPositionCache::GeolocationPositionCache):
+ (WebCore::GeolocationPositionCache::addUser):
+ (WebCore::GeolocationPositionCache::removeUser):
+ (WebCore::GeolocationPositionCache::setDatabasePath):
+ (WebCore::GeolocationPositionCache::setCachedPosition):
+ (WebCore::GeolocationPositionCache::cachedPosition):
+ (WebCore::GeolocationPositionCache::startBackgroundThread):
+ (WebCore::GeolocationPositionCache::threadEntryPoint):
+ (WebCore::GeolocationPositionCache::threadEntryPointImpl):
+ (WebCore::GeolocationPositionCache::triggerReadFromDatabase):
+ (WebCore::GeolocationPositionCache::readFromDatabase):
+ (WebCore::GeolocationPositionCache::readFromDatabaseImpl):
+ (WebCore::GeolocationPositionCache::triggerWriteToDatabase):
+ (WebCore::GeolocationPositionCache::writeToDatabase):
+ (WebCore::GeolocationPositionCache::writeToDatabaseImpl):
+ * page/GeolocationPositionCache.h:
+ * page/Geoposition.h:
+ (WebCore::Geoposition::threadSafeCopy):
+ (WebCore::Geoposition::Geoposition):
+
2010-12-20 Andras Becsi <abecsi at webkit.org>
Unreviewed build fix.
diff --git a/WebCore/page/Coordinates.h b/WebCore/page/Coordinates.h
index 50003ce..6365548 100644
--- a/WebCore/page/Coordinates.h
+++ b/WebCore/page/Coordinates.h
@@ -32,12 +32,15 @@
namespace WebCore {
-typedef int ExceptionCode;
-
class Coordinates : public RefCounted<Coordinates> {
public:
static PassRefPtr<Coordinates> create(double latitude, double longitude, bool providesAltitude, double altitude, double accuracy, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed) { return adoptRef(new Coordinates(latitude, longitude, providesAltitude, altitude, accuracy, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed)); }
-
+
+ PassRefPtr<Coordinates> threadSafeCopy() const
+ {
+ return Coordinates::create(m_latitude, m_longitude, m_canProvideAltitude, m_altitude, m_accuracy, m_canProvideAltitudeAccuracy, m_altitudeAccuracy, m_canProvideHeading, m_heading, m_canProvideSpeed, m_speed);
+ }
+
double latitude() const { return m_latitude; }
double longitude() const { return m_longitude; }
double altitude() const { return m_altitude; }
diff --git a/WebCore/page/GeolocationPositionCache.cpp b/WebCore/page/GeolocationPositionCache.cpp
index 9b93b03..4a9c6b7 100644
--- a/WebCore/page/GeolocationPositionCache.cpp
+++ b/WebCore/page/GeolocationPositionCache.cpp
@@ -28,12 +28,17 @@
#if ENABLE(GEOLOCATION)
+#include "CrossThreadTask.h"
#include "Geoposition.h"
#include "SQLValue.h"
#include "SQLiteDatabase.h"
#include "SQLiteFileSystem.h"
#include "SQLiteStatement.h"
#include "SQLiteTransaction.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Threading.h>
+
+using namespace WTF;
namespace WebCore {
@@ -48,55 +53,93 @@ GeolocationPositionCache* GeolocationPositionCache::instance()
}
GeolocationPositionCache::GeolocationPositionCache()
- : m_haveReadFromDatabase(false)
+ : m_threadId(0)
{
}
void GeolocationPositionCache::addUser()
{
ASSERT(numUsers >= 0);
+ if (!numUsers && !m_threadId) {
+ startBackgroundThread();
+ MutexLocker lock(m_cachedPositionMutex);
+ if (!m_cachedPosition)
+ triggerReadFromDatabase();
+ }
++numUsers;
}
void GeolocationPositionCache::removeUser()
{
- if (!(--numUsers) && m_cachedPosition)
- writeToDatabase();
+ MutexLocker lock(m_cachedPositionMutex);
+ --numUsers;
ASSERT(numUsers >= 0);
+ if (!numUsers && m_cachedPosition)
+ triggerWriteToDatabase();
}
void GeolocationPositionCache::setDatabasePath(const String& path)
{
static const char* databaseName = "CachedGeoposition.db";
String newFile = SQLiteFileSystem::appendDatabaseFileNameToPath(path, databaseName);
+ MutexLocker lock(m_databaseFileMutex);
if (m_databaseFile != newFile) {
m_databaseFile = newFile;
- m_haveReadFromDatabase = false;
+ if (numUsers && !m_cachedPosition)
+ triggerReadFromDatabase();
}
}
void GeolocationPositionCache::setCachedPosition(Geoposition* cachedPosition)
{
+ MutexLocker lock(m_cachedPositionMutex);
m_cachedPosition = cachedPosition;
}
Geoposition* GeolocationPositionCache::cachedPosition()
{
- if (!m_haveReadFromDatabase && !m_cachedPosition)
- readFromDatabase();
+ MutexLocker lock(m_cachedPositionMutex);
return m_cachedPosition.get();
}
-void GeolocationPositionCache::readFromDatabase()
+void GeolocationPositionCache::startBackgroundThread()
+{
+ // FIXME: Consider sharing this thread with other background tasks.
+ m_threadId = createThread(threadEntryPoint, this, "WebCore: GeolocationPositionCache");
+}
+
+void* GeolocationPositionCache::threadEntryPoint(void* object)
{
- ASSERT(!m_haveReadFromDatabase);
- ASSERT(!m_cachedPosition);
+ static_cast<GeolocationPositionCache*>(object)->threadEntryPointImpl();
+ return 0;
+}
- m_haveReadFromDatabase = true;
+void GeolocationPositionCache::threadEntryPointImpl()
+{
+ while (OwnPtr<ScriptExecutionContext::Task> task = m_queue.waitForMessage()) {
+ // We don't need a ScriptExecutionContext in the callback, so pass 0 here.
+ task->performTask(0);
+ }
+}
+
+void GeolocationPositionCache::triggerReadFromDatabase()
+{
+ m_queue.append(createCallbackTask(&GeolocationPositionCache::readFromDatabase, this));
+}
+
+void GeolocationPositionCache::readFromDatabase(ScriptExecutionContext*, GeolocationPositionCache* cache)
+{
+ cache->readFromDatabaseImpl();
+}
+void GeolocationPositionCache::readFromDatabaseImpl()
+{
SQLiteDatabase database;
- if (!database.open(m_databaseFile))
- return;
+ {
+ MutexLocker lock(m_databaseFileMutex);
+ if (!database.open(m_databaseFile))
+ return;
+ }
// Create the table here, such that even if we've just created the
// DB, the commands below should succeed.
@@ -129,16 +172,40 @@ void GeolocationPositionCache::readFromDatabase()
providesAltitudeAccuracy, statement.getColumnDouble(4), // altitudeAccuracy
providesHeading, statement.getColumnDouble(5), // heading
providesSpeed, statement.getColumnDouble(6)); // speed
- m_cachedPosition = Geoposition::create(coordinates.release(), statement.getColumnInt64(7)); // timestamp
+ DOMTimeStamp timestamp = statement.getColumnInt64(7); // timestamp
+
+ // A position may have been set since we called triggerReadFromDatabase().
+ MutexLocker lock(m_cachedPositionMutex);
+ if (m_cachedPosition)
+ return;
+ m_cachedPosition = Geoposition::create(coordinates.release(), timestamp);
}
-void GeolocationPositionCache::writeToDatabase()
+void GeolocationPositionCache::triggerWriteToDatabase()
{
- ASSERT(m_cachedPosition);
+ m_queue.append(createCallbackTask(writeToDatabase, this));
+}
+void GeolocationPositionCache::writeToDatabase(ScriptExecutionContext*, GeolocationPositionCache* cache)
+{
+ cache->writeToDatabaseImpl();
+}
+
+void GeolocationPositionCache::writeToDatabaseImpl()
+{
SQLiteDatabase database;
- if (!database.open(m_databaseFile))
- return;
+ {
+ MutexLocker lock(m_databaseFileMutex);
+ if (!database.open(m_databaseFile))
+ return;
+ }
+
+ RefPtr<Geoposition> cachedPosition;
+ {
+ MutexLocker lock(m_cachedPositionMutex);
+ if (m_cachedPosition)
+ cachedPosition = m_cachedPosition->threadSafeCopy();
+ }
SQLiteTransaction transaction(database);
@@ -158,26 +225,27 @@ void GeolocationPositionCache::writeToDatabase()
if (statement.prepare() != SQLResultOk)
return;
- statement.bindDouble(1, m_cachedPosition->coords()->latitude());
- statement.bindDouble(2, m_cachedPosition->coords()->longitude());
- if (m_cachedPosition->coords()->canProvideAltitude())
- statement.bindDouble(3, m_cachedPosition->coords()->altitude());
+ statement.bindDouble(1, cachedPosition->coords()->latitude());
+ statement.bindDouble(2, cachedPosition->coords()->longitude());
+ if (cachedPosition->coords()->canProvideAltitude())
+ statement.bindDouble(3, cachedPosition->coords()->altitude());
else
statement.bindNull(3);
- statement.bindDouble(4, m_cachedPosition->coords()->accuracy());
- if (m_cachedPosition->coords()->canProvideAltitudeAccuracy())
- statement.bindDouble(5, m_cachedPosition->coords()->altitudeAccuracy());
+ statement.bindDouble(4, cachedPosition->coords()->accuracy());
+ if (cachedPosition->coords()->canProvideAltitudeAccuracy())
+ statement.bindDouble(5, cachedPosition->coords()->altitudeAccuracy());
else
statement.bindNull(5);
- if (m_cachedPosition->coords()->canProvideHeading())
- statement.bindDouble(6, m_cachedPosition->coords()->heading());
+ if (cachedPosition->coords()->canProvideHeading())
+ statement.bindDouble(6, cachedPosition->coords()->heading());
else
statement.bindNull(6);
- if (m_cachedPosition->coords()->canProvideSpeed())
- statement.bindDouble(7, m_cachedPosition->coords()->speed());
+ if (cachedPosition->coords()->canProvideSpeed())
+ statement.bindDouble(7, cachedPosition->coords()->speed());
else
statement.bindNull(7);
- statement.bindInt64(8, m_cachedPosition->timestamp());
+ statement.bindInt64(8, cachedPosition->timestamp());
+
if (!statement.executeCommand())
return;
diff --git a/WebCore/page/GeolocationPositionCache.h b/WebCore/page/GeolocationPositionCache.h
index 5053848..1398850 100644
--- a/WebCore/page/GeolocationPositionCache.h
+++ b/WebCore/page/GeolocationPositionCache.h
@@ -27,7 +27,10 @@
#define GeolocationPositionCache_h
#include "PlatformString.h"
+#include "ScriptExecutionContext.h"
+
#include <wtf/Forward.h>
+#include <wtf/MessageQueue.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
@@ -35,6 +38,10 @@ namespace WebCore {
class Geoposition;
+// Maintains a cached position for Geolocation. Takes care of writing and
+// reading the position to a database on a background thread. The Geolocation
+// spec does not require a cached position to be maintained, so we take a
+// best-effort approach where we do not wait for database reads or writes.
class GeolocationPositionCache {
public:
static GeolocationPositionCache* instance();
@@ -49,12 +56,23 @@ public:
private:
GeolocationPositionCache();
- void readFromDatabase();
- void writeToDatabase();
+ void startBackgroundThread();
+ static void* threadEntryPoint(void* object);
+ void threadEntryPointImpl();
+
+ void triggerReadFromDatabase();
+ static void readFromDatabase(ScriptExecutionContext*, GeolocationPositionCache*);
+ void readFromDatabaseImpl();
+ void triggerWriteToDatabase();
+ static void writeToDatabase(ScriptExecutionContext*, GeolocationPositionCache*);
+ void writeToDatabaseImpl();
RefPtr<Geoposition> m_cachedPosition;
+ Mutex m_cachedPositionMutex;
+ ThreadIdentifier m_threadId;
+ MessageQueue<ScriptExecutionContext::Task> m_queue;
String m_databaseFile;
- bool m_haveReadFromDatabase;
+ Mutex m_databaseFileMutex;
};
} // namespace WebCore
diff --git a/WebCore/page/Geoposition.h b/WebCore/page/Geoposition.h
index 8b215b1..83d865a 100644
--- a/WebCore/page/Geoposition.h
+++ b/WebCore/page/Geoposition.h
@@ -33,8 +33,6 @@
namespace WebCore {
-typedef int ExceptionCode;
-
class Geoposition : public RefCounted<Geoposition> {
public:
static PassRefPtr<Geoposition> create(PassRefPtr<Coordinates> coordinates, DOMTimeStamp timestamp)
@@ -42,6 +40,11 @@ public:
return adoptRef(new Geoposition(coordinates, timestamp));
}
+ PassRefPtr<Geoposition> threadSafeCopy() const
+ {
+ return Geoposition::create(m_coordinates->threadSafeCopy(), m_timestamp);
+ }
+
DOMTimeStamp timestamp() const { return m_timestamp; }
Coordinates* coords() const { return m_coordinates.get(); }
@@ -50,6 +53,7 @@ private:
: m_coordinates(coordinates)
, m_timestamp(timestamp)
{
+ ASSERT(m_coordinates);
}
RefPtr<Coordinates> m_coordinates;
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list