WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
27836
Stale database version persists through browser refresh (changeVersion doesn't work)
https://bugs.webkit.org/show_bug.cgi?id=27836
Summary
Stale database version persists through browser refresh (changeVersion doesn'...
Matthew Bolohan
Reported
2009-07-30 07:50:25 PDT
Created
attachment 33778
[details]
Script that demonstrates incorrect caching of database version
r46507
The version property of the database object is stale after invoking changeVersion() and remains stale after a refresh. Killing webkit results in a correct value for db.version after calling window.openDatabase(). I have attached a test script that demonstrates this behavior. The script performs the following steps: 1) open a new database without a version restriction 2) check if the database version matches a predefined string constant (report success if the versions match) 3) if the versions don't match, change the database version to the predefined version constant 4) reload the page Expected behavior: - version doesn't match - change version (alert changeVersion success and reload) - version matches (alert success with version) Observed behavior: - version doesn't match - change version (alert changeVersion success and reload) - version doesn't match - change version (alert Error: current version of the database and `oldVersion` argument do not match) Note: Killing webkit and loading the script results in a successful version match.
Attachments
Script that demonstrates incorrect caching of database version
(910 bytes, text/html)
2009-07-30 07:50 PDT
,
Matthew Bolohan
no flags
Details
Proposed patch with layout test.
(9.61 KB, patch)
2009-09-07 09:05 PDT
,
Ben Murdoch
no flags
Details
Formatted Diff
Diff
another test
(1.65 KB, text/html)
2009-09-07 10:18 PDT
,
Alexey Proskuryakov
no flags
Details
Patch incorporating Alexey's test
(13.16 KB, patch)
2009-09-11 06:44 PDT
,
Ben Murdoch
ddkilzer
: review-
Details
Formatted Diff
Diff
Revised patch.
(16.16 KB, patch)
2009-10-01 08:36 PDT
,
Ben Murdoch
ddkilzer
: review+
ddkilzer
: commit-queue-
Details
Formatted Diff
Diff
Show Obsolete
(2)
View All
Add attachment
proposed patch, testcase, etc.
Alexey Proskuryakov
Comment 1
2009-08-05 18:03:25 PDT
<
rdar://problem/5737246
>
Alexey Proskuryakov
Comment 2
2009-08-05 18:03:51 PDT
<
rdar://problem/5556376
> even.
Alexey Proskuryakov
Comment 3
2009-08-25 11:56:46 PDT
***
Bug 28418
has been marked as a duplicate of this bug. ***
Ben Murdoch
Comment 4
2009-09-07 08:14:54 PDT
I think I know what is happening here and will send a patch shortly.
Ben Murdoch
Comment 5
2009-09-07 09:05:28 PDT
Created
attachment 39150
[details]
Proposed patch with layout test. This patch fixes this bug and 24818 which although similar is actually not a duplicate. The problem described in this bug is caused by the database only being removed from the guid->version map in the Database dtor. The dtor is only called when the Database thread is destroyed which may come after the page has been unloaded and the next page loaded. Thus in the test script attached to this bug, the map still contains the old database version number when the page is reloaded because the dtor has at that point not been run. This is fixed by moving the code from the dtor into the Database::close() method. The bug described in 24818 comes from the fact that in the Database::setExcpectedVersion (called from the ChangeVersionWrapper postflight code) we do not update the guid->version map. This is fixed by adding code to update the map at that point. I've also implemented the changeVersion function in the V8 bindings and written a layout test that is a combination of the test attached to this bug and that attached to 24818.
Alexey Proskuryakov
Comment 6
2009-09-07 10:18:40 PDT
Created
attachment 39154
[details]
another test FWIW, here is a test that I had sitting in my tree disabled for quite a while.
Ben Murdoch
Comment 7
2009-09-07 10:39:33 PDT
(In reply to
comment #6
)
> Created an attachment (id=39154) [details] > another test > > FWIW, here is a test that I had sitting in my tree disabled for quite a while.
Thanks Alexey, confirming that that test seems to work fine with the fix applied (displays the foobar error and no asserts on reload). Would you like me to add it to the patch? Cheers, Ben
Alexey Proskuryakov
Comment 8
2009-09-07 11:00:53 PDT
Not sure, I haven't compared it with your test carefully enough. If you think there's something additional that it tests, then adding it would be great.
Ben Murdoch
Comment 9
2009-09-08 08:50:25 PDT
(In reply to
comment #8
)
> Not sure, I haven't compared it with your test carefully enough. If you think > there's something additional that it tests, then adding it would be great.
I think your test is valuable in addition to mine as it verifies that the DB handle stays alive (my test opens new handles). After I get some review feedback I will add your test into the patch. Cheers, Ben
Ben Murdoch
Comment 10
2009-09-08 11:49:16 PDT
cc'ing dglazkov as part of this patch is an edit to V8 bindings.
Ben Murdoch
Comment 11
2009-09-10 11:57:09 PDT
ping...
Adam Barth
Comment 12
2009-09-10 12:27:45 PDT
Comment on
attachment 39150
[details]
Proposed patch with layout test. The V8 parts of this patch look fine to me. I'm not that confident in the non-V8 parts, but I'm presuming AP has looked them over.
Alexey Proskuryakov
Comment 13
2009-09-10 13:06:50 PDT
> I'm presuming AP has looked them over.
I did not. I'm not very familiar with this code.
Adam Barth
Comment 14
2009-09-10 13:11:25 PDT
Comment on
attachment 39150
[details]
Proposed patch with layout test. Hum... Ok. Then I'm putting this back to r?. The V8 parts are fine. We need to find someone familiar with database to look at the rest of the patch.
Ben Murdoch
Comment 15
2009-09-11 02:37:03 PDT
(In reply to
comment #14
)
> (From update of
attachment 39150
[details]
) > Hum... Ok. Then I'm putting this back to r?. The V8 parts are fine. We need > to find someone familiar with database to look at the rest of the patch.
Thanks for looking over the V8 portion Adam. There have been a few patches to the WebCore storage code since I sent this patch so I need to regenerate it. dglazkov seems to have reviewed those refactorings, so perhaps he could review this one too? I will also cc Brady when I send the new patch because AFAIK he wrote the code originally. Cheers, Ben
Ben Murdoch
Comment 16
2009-09-11 06:32:49 PDT
Seems that the recent DB refactorings didn't touch the same areas as this patch as it still applied after a sync. I've added ap's test into the patch now and will upload a new version.
Ben Murdoch
Comment 17
2009-09-11 06:44:32 PDT
Created
attachment 39426
[details]
Patch incorporating Alexey's test New patch generated more recently and including Alexey's test.
Ben Murdoch
Comment 18
2009-09-11 06:51:00 PDT
Brady, would you mind taking a look at this patch? Many thanks, Ben
Ben Murdoch
Comment 19
2009-09-15 13:44:29 PDT
Ping... anyone able to take a look at this? Thanks, Ben
Eric Seidel (no email)
Comment 20
2009-09-23 17:15:57 PDT
Comment on
attachment 39426
[details]
Patch incorporating Alexey's test Why not just put: 178 { 179 MutexLocker locker(guidMutex()); 180 181 HashSet<Database*>* hashSet = guidToDatabaseMap().get(m_guid); 182 ASSERT(hashSet); 183 ASSERT(hashSet->contains(this)); 184 hashSet->remove(this); 185 if (hashSet->isEmpty()) { 186 guidToDatabaseMap().remove(m_guid); 187 delete hashSet; 188 guidToVersionMap().remove(m_guid); 189 } 190 } 191 into a static inline function? Also, I think Alexey is really your man here.
Ben Murdoch
Comment 21
2009-09-25 06:08:53 PDT
(In reply to
comment #20
) Hi Eric, Thanks for looking at my patch!
> (From update of
attachment 39426
[details]
) > Why not just put: > 178 { > 179 MutexLocker locker(guidMutex()); > 180 > 181 HashSet<Database*>* hashSet = guidToDatabaseMap().get(m_guid); > 182 ASSERT(hashSet); > 183 ASSERT(hashSet->contains(this)); > 184 hashSet->remove(this); > 185 if (hashSet->isEmpty()) { > 186 guidToDatabaseMap().remove(m_guid); > 187 delete hashSet; > 188 guidToVersionMap().remove(m_guid); > 189 } > 190 } > 191 > into a static inline function?
As this code is only called once and my intention was to just move it from the destructor to the close() method, it's not clear to me what moving it into a static inline would buy us. Could you elaborate?
> Also, I think Alexey is really your man here.
Alexey already looked at it and said he wasn't familiar enough with the code to review it (
comment 13
above). So could you please help me with getting this reviewed? Adam has OK'd the V8 portion (
comment 12
). Cheers, Ben
David Kilzer (:ddkilzer)
Comment 22
2009-09-26 10:45:36 PDT
Comment on
attachment 39426
[details]
Patch incorporating Alexey's test
> Index: WebCore/storage/Database.cpp > =================================================================== > --- WebCore/storage/Database.cpp (revision 48292) > +++ WebCore/storage/Database.cpp (working copy) > @@ -328,6 +314,20 @@ void Database::close() > m_sqliteDatabase.close(); > m_document->databaseThread()->recordDatabaseClosed(this); > m_opened = false; > + > + { > + MutexLocker locker(guidMutex()); > + > + HashSet<Database*>* hashSet = guidToDatabaseMap().get(m_guid); > + ASSERT(hashSet); > + ASSERT(hashSet->contains(this)); > + hashSet->remove(this); > + if (hashSet->isEmpty()) { > + guidToDatabaseMap().remove(m_guid); > + delete hashSet; > + guidToVersionMap().remove(m_guid); > + } > + } > } > } >
I think moving this code from the Database destructor to the close() method is fine. (Running all database tests with a debug build of WebKit after this change would be a really good idea. Have you done that?)
> @@ -631,6 +631,9 @@ Vector<String> Database::tableNames() > void Database::setExpectedVersion(const String& version) > { > m_expectedVersion = version.copy(); > + // Update the in memory database version map. > + MutexLocker locker(guidMutex()); > + guidToVersionMap().set(m_guid, version); > }
There is similar GUID-setting code in Database::performOpenAndVerify() that does two things this code does not: 1. It maps an empty string to a null string before updating the guidToVersionMap(). 2. It makes a defensive copy of the version string (if it is not an empty string). I think it would make sense to extract this code into its own static inline method (perhaps after the guidToVersionMap() method itself) and update the two call sites to use it. r- to fix Database::setExpectedVersion().
Dumitru Daniliuc
Comment 23
2009-09-28 12:47:09 PDT
the DB changes look good to me. thanks for catching this problem and fixing it! minor: please add a short comment to Database::setVersionInDatabase() explaining that INSERT will replace the old version because that's how the table is defined.
> Index: LayoutTests/storage/change-version-expected.txt > =================================================================== > --- LayoutTests/storage/change-version-expected.txt (revision 0) > +++ LayoutTests/storage/change-version-expected.txt (revision 0) > @@ -0,0 +1,4 @@ > +This test verifies that the database.changeVersion function works as expected.
minor: Database::changeVersion().
> Property changes on: LayoutTests/storage/change-version-expected.txt > ___________________________________________________________________ > Added: svn:eol-style > + native
i don't think these are necessary.
> Index: LayoutTests/storage/change-version-handle-reuse.html > +function finishTest() > +{ > + log("TEST COMPLETE.");
replace tab with spaces.
> +function runTest() > +{ > + if (window.layoutTestController) { > + layoutTestController.waitUntilDone();
tab --> spaces.
> Index: LayoutTests/storage/change-version.html > +function changeVersionCallback(tx) > +{ > + tx.executeSql('drop table if exists info;', [], emptyFunction, emptyFunction); > + tx.executeSql('create table if not exists info (version INTEGER);',[], emptyFunction, emptyFunction); > + tx.executeSql('insert into info values(?);', [EXPECTED_VERSION_AFTER_RELOAD], emptyFunction, emptyFunction); > +}
minor: i believe webkit code and tests always capitalize keywords such as DROP, CREATE TABLE, INSERT, etc. and uses double-quotes (") for strings.
> +function runTest() > +{ > + if (window.location.search == "?2") { > + db = window.openDatabase('changeversion-test', '', 'Test for the database.changeVersion() function', 1024); > + log('Finished tests with version ' + db.version);
minor: maybe change the log message to something like: log("Finished tests with version " + db.version + "; expected version: " + EXPECTED_VERSION_AFTER_RELOAD);
> + finishTest(); > + } else { > + testPart1(); > + }
1-line else: remove {}. minor: maybe put the if-block into a testPart2() function?
> +function testPart1() { > + if (window.layoutTestController) { > + layoutTestController.clearAllDatabases(); > + layoutTestController.dumpAsText(); > + layoutTestController.waitUntilDone(); > + } > + > + db = window.openDatabase('changeversion-test', '', 'Test for the database.changeVersion() function', 1024); > + > + if (db.version != EXPECTED_VERSION_AFTER_RELOAD) { > + // First run Hixie's test to ensure basic changeVersion functionality works (see
bug 28418
). > + db.changeVersion('', EXPECTED_VERSION_AFTER_HIXIE_TEST, emptyFunction, function (e) { > + log('FAIL in changeVersion:' + e); > + finishTest(); > + }, function () { > + try { > + var db2 = openDatabase('change-version-test', EXPECTED_VERSION_AFTER_HIXIE_TEST, '', 0); > + } catch (e) { > + log('FAIL in openDatabase: ' + e); > + finishTest(); > + } > + // Following versions should match. > + log('Database version: ' + db.version); > + log('Second database version: ' + db2.version);
instead of expecting the user to know that the two versions are supposed to match, maybe replace these lines with something like this? if (db.version == db2.version) log("db.version(" + db.version + ") matches db2.version(" + db2.version + ") as expected."); else log("db.version(" + db.version + ") does not db2.version(" + db2.version + "): failing.");
Ben Murdoch
Comment 24
2009-09-28 12:54:57 PDT
Thank you for the feedback David and Dumi. I'll incorporate your comments into a new patch and upload. Cheers!
Ben Murdoch
Comment 25
2009-10-01 08:35:03 PDT
(In reply to
comment #22
)
> (Running all database tests with a debug build of WebKit after this > change would be a really good idea. Have you done that?)
Yes, I've run the storage layout tests on Mac and Windows and they all pass.
> > There is similar GUID-setting code in Database::performOpenAndVerify() that > does two things this code does not: > > 1. It maps an empty string to a null string before updating the > guidToVersionMap(). > 2. It makes a defensive copy of the version string (if it is not an empty > string). > > I think it would make sense to extract this code into its own static inline > method (perhaps after the guidToVersionMap() method itself) and update the two > call sites to use it. >
Fixed. (In reply to
comment #23
)
> minor: please add a short comment to Database::setVersionInDatabase() > explaining that INSERT will replace the old version because that's how the > table is defined.
Done.
> > Index: LayoutTests/storage/change-version-expected.txt > > =================================================================== > > --- LayoutTests/storage/change-version-expected.txt (revision 0) > > +++ LayoutTests/storage/change-version-expected.txt (revision 0) > > @@ -0,0 +1,4 @@ > > +This test verifies that the database.changeVersion function works as expected.
>
>minor: Database::changeVersion().
IMHO as it's the JS function we're testing, I think database.changeVersion is fine. >
> > Property changes on: LayoutTests/storage/change-version-expected.txt > > ___________________________________________________________________ > > Added: svn:eol-style > > + native > > i don't think these are necessary.
Hmm, I was advised on a past review that they should be set. Keeping for now.
> > > Index: LayoutTests/storage/change-version-handle-reuse.html > > +function finishTest() > > +{ > > + log("TEST COMPLETE."); > > replace tab with spaces.
Done.
> > > +function runTest() > > +{ > > + if (window.layoutTestController) { > > + layoutTestController.waitUntilDone(); > > tab --> spaces.
Done.
> > > Index: LayoutTests/storage/change-version.html > > +function changeVersionCallback(tx) > > +{ > > + tx.executeSql('drop table if exists info;', [], emptyFunction, emptyFunction); > > + tx.executeSql('create table if not exists info (version INTEGER);',[], emptyFunction, emptyFunction); > > + tx.executeSql('insert into info values(?);', [EXPECTED_VERSION_AFTER_RELOAD], emptyFunction, emptyFunction); > > +} > > minor: i believe webkit code and tests always capitalize keywords such as DROP, > CREATE TABLE, INSERT, etc. and uses double-quotes (") for strings.
Done.
> > > +function runTest() > > +{ > > + if (window.location.search == "?2") { > > + db = window.openDatabase('changeversion-test', '', 'Test for the database.changeVersion() function', 1024); > > + log('Finished tests with version ' + db.version); > > minor: maybe change the log message to something like: > > log("Finished tests with version " + db.version + "; expected version: " + > EXPECTED_VERSION_AFTER_RELOAD);
Done.
> > > + finishTest(); > > + } else { > > + testPart1(); > > + } > > 1-line else: remove {}.
Fixed.
> > minor: maybe put the if-block into a testPart2() function? > > > +function testPart1() { > > + if (window.layoutTestController) { > > + layoutTestController.clearAllDatabases(); > > + layoutTestController.dumpAsText(); > > + layoutTestController.waitUntilDone(); > > + } > > + > > + db = window.openDatabase('changeversion-test', '', 'Test for the database.changeVersion() function', 1024); > > + > > + if (db.version != EXPECTED_VERSION_AFTER_RELOAD) { > > + // First run Hixie's test to ensure basic changeVersion functionality works (see
bug 28418
). > > + db.changeVersion('', EXPECTED_VERSION_AFTER_HIXIE_TEST, emptyFunction, function (e) { > > + log('FAIL in changeVersion:' + e); > > + finishTest(); > > + }, function () { > > + try { > > + var db2 = openDatabase('change-version-test', EXPECTED_VERSION_AFTER_HIXIE_TEST, '', 0); > > + } catch (e) { > > + log('FAIL in openDatabase: ' + e); > > + finishTest(); > > + } > > + // Following versions should match. > > + log('Database version: ' + db.version); > > + log('Second database version: ' + db2.version); > > instead of expecting the user to know that the two versions are supposed to > match, maybe replace these lines with something like this? > > if (db.version == db2.version) > log("db.version(" + db.version + ") matches db2.version(" + db2.version + > ") as expected."); > else > log("db.version(" + db.version + ") does not db2.version(" + db2.version + > "): failing.");
Done. New patch is on it's way!
Ben Murdoch
Comment 26
2009-10-01 08:36:19 PDT
Created
attachment 40445
[details]
Revised patch.
Dumitru Daniliuc
Comment 27
2009-10-01 11:40:55 PDT
Comment on
attachment 40445
[details]
Revised patch. LGTM, with 2 minor comments below. I'm not a reviewer though, so I can't r+ the patch.
> Index: WebCore/storage/Database.cpp > =================================================================== > --- WebCore/storage/Database.cpp (revision 48292) > +++ WebCore/storage/Database.cpp (working copy) > @@ -89,6 +89,18 @@ static GuidVersionMap& guidToVersionMap( > return map; > } > > +static inline void updateGuidVersionMap(int guid, String newVersion) > +{ > + // Note: It is not safe to put an empty string into the guidToVersionMap() map. > + // That's because the map is cross-thread, but empty strings are per-thread. > + // The copy() function makes a version of the string you can use on the current > + // thread, but we need a string we can keep in a cross-thread data structure. > + // FIXME: This is a quite-awkward restriction to have to program with. > + > + // NOTE: Caller must lock guidMutex().
optional: might be a good idea to make this a function-level comment (ie. put it right before 'static inline void ...').
> Index: LayoutTests/storage/change-version.html > =================================================================== > + // The two database versions should match. > + if (db.version == db2.version) > + log("PASS: db.version(" + db.version + ") matches db2.version(" + db2.version +") as expected."); > + else > + log("FAIL: db.version(" + db.version + ") does not db2.version(" + db2.version +")");
typo (that i had in my comment too :)): does not MATCH db2.version
Ben Murdoch
Comment 28
2009-10-01 11:48:23 PDT
(In reply to
comment #27
) Thanks Dumi -- if David is happy with the patch and can r+ I will address your comments when I commit. Cheers, Ben
> (From update of
attachment 40445
[details]
) > LGTM, with 2 minor comments below. I'm not a reviewer though, so I can't r+ the > patch. > > > Index: WebCore/storage/Database.cpp > > =================================================================== > > --- WebCore/storage/Database.cpp (revision 48292) > > +++ WebCore/storage/Database.cpp (working copy) > > @@ -89,6 +89,18 @@ static GuidVersionMap& guidToVersionMap( > > return map; > > } > > > > +static inline void updateGuidVersionMap(int guid, String newVersion) > > +{ > > + // Note: It is not safe to put an empty string into the guidToVersionMap() map. > > + // That's because the map is cross-thread, but empty strings are per-thread. > > + // The copy() function makes a version of the string you can use on the current > > + // thread, but we need a string we can keep in a cross-thread data structure. > > + // FIXME: This is a quite-awkward restriction to have to program with. > > + > > + // NOTE: Caller must lock guidMutex(). > > optional: might be a good idea to make this a function-level comment (ie. put > it right before 'static inline void ...'). > > > Index: LayoutTests/storage/change-version.html > > =================================================================== > > + // The two database versions should match. > > + if (db.version == db2.version) > > + log("PASS: db.version(" + db.version + ") matches db2.version(" + db2.version +") as expected."); > > + else > > + log("FAIL: db.version(" + db.version + ") does not db2.version(" + db2.version +")"); > > typo (that i had in my comment too :)): does not MATCH db2.version
David Kilzer (:ddkilzer)
Comment 29
2009-10-01 14:08:42 PDT
(In reply to
comment #27
)
> (From update of
attachment 40445
[details]
) > > Index: WebCore/storage/Database.cpp > > =================================================================== > > --- WebCore/storage/Database.cpp (revision 48292) > > +++ WebCore/storage/Database.cpp (working copy) > > @@ -89,6 +89,18 @@ static GuidVersionMap& guidToVersionMap( > > return map; > > } > > > > +static inline void updateGuidVersionMap(int guid, String newVersion) > > +{ > > + // Note: It is not safe to put an empty string into the guidToVersionMap() map. > > + // That's because the map is cross-thread, but empty strings are per-thread. > > + // The copy() function makes a version of the string you can use on the current > > + // thread, but we need a string we can keep in a cross-thread data structure. > > + // FIXME: This is a quite-awkward restriction to have to program with. > > + > > + // NOTE: Caller must lock guidMutex(). > > optional: might be a good idea to make this a function-level comment (ie. put > it right before 'static inline void ...').
I prefer the comment inside the method as it is above. Putting it outside the method makes it harder to visually parse the file when looking for the method name (IMO). Reviewing the new patch now.
David Kilzer (:ddkilzer)
Comment 30
2009-10-01 14:20:41 PDT
Comment on
attachment 40445
[details]
Revised patch.
> Index: WebCore/ChangeLog > [...] > + * bindings/v8/custom/V8DatabaseCustom.cpp: > + (WebCore::CALLBACK_FUNC_DECL): implement the V8 binding for database.changeVersion > + (WebCore::createTransaction): Fix a bug that was checking the wrong argument index to save the success callback
Would be nice if these comments both started with capital letters and ended with periods (like the ones below).
> + * storage/Database.cpp: > + (WebCore::updateGuidVersionMap): Safely update the Guid/version hash map. > + (WebCore::Database::~Database): Remove code that removes the database from the guid->database and guid->version maps. > + (WebCore::Database::setVersionInDatabase): Add a comment to explain some behaviour. > + (WebCore::Database::close): Move the code that updates the maps from the destructor to here. > + (WebCore::Database::performOpenAndVerify): Call updateGuidVersionMap instead of setting the hash map directly. > + (WebCore::Database::setExpectedVersion): Update the in memory guid->version map when we want to update the database version.
> Index: WebCore/storage/Database.cpp > [...] > +static inline void updateGuidVersionMap(int guid, String newVersion) > +{ > + // Note: It is not safe to put an empty string into the guidToVersionMap() map. > + // That's because the map is cross-thread, but empty strings are per-thread. > + // The copy() function makes a version of the string you can use on the current > + // thread, but we need a string we can keep in a cross-thread data structure. > + // FIXME: This is a quite-awkward restriction to have to program with. > + > + // NOTE: Caller must lock guidMutex().
Oops, I see what Dumi meant. This one-line comment could go above the 'static inline' method declaration. It would be nice to add this comment above the code (in case someone skips over the large block above): // Map null string to empty string (see comment above).
> + guidToVersionMap().set(guid, newVersion.isEmpty() ? String() : newVersion.copy()); > +}
> bool Database::setVersionInDatabase(const String& version) > { > + // The INSERT will replace an existing entry for the database with the new version number, due to the UNIQUE ON CONFLICT REPLACE > + // clause in the CREATE statement (see Database::performOpenAndVerify)
This comment needs a period. Would be nice to add "()" after "performOpenAndVerify" so you know you're looking for a method.
> @@ -447,12 +461,6 @@ bool Database::performOpenAndVerify(Exce > { > MutexLocker locker(guidMutex()); > > - // Note: It is not safe to put an empty string into the guidToVersionMap() map. > - // That's because the map is cross-thread, but empty strings are per-thread. > - // The copy() function makes a version of the string you can use on the current > - // thread, but we need a string we can keep in a cross-thread data structure. > - // FIXME: This is a quite-awkward restriction to have to program with. > - > GuidVersionMap::iterator entry = guidToVersionMap().find(m_guid); > if (entry != guidToVersionMap().end()) { > // Map null string to empty string (see comment above).
This comment needs to change since you moved the big comment: // Map null string to empty string (see updateGuidVersionMap()). r=me with the above changes.
Ben Murdoch
Comment 31
2009-10-02 03:36:27 PDT
Landed as
r49018
.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug