Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: chrome/browser/chromeos/gdata/gdata_file_system.cc

Issue 10270035: gdata: Fix a bug where |root_| was accessed without a lock (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/chromeos/gdata/gdata_file_system.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/gdata/gdata_file_system.h" 5 #include "chrome/browser/chromeos/gdata/gdata_file_system.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <sys/stat.h> 8 #include <sys/stat.h>
9 9
10 #include <set> 10 #include <set>
(...skipping 1041 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 const FindEntryCallback& callback) { 1052 const FindEntryCallback& callback) {
1053 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1053 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1054 1054
1055 base::AutoLock lock(lock_); 1055 base::AutoLock lock(lock_);
1056 if (root_->origin() == INITIALIZING) { 1056 if (root_->origin() == INITIALIZING) {
1057 // If root feed is not initialized but the initilization process has 1057 // If root feed is not initialized but the initilization process has
1058 // already started, add an observer to execute the remaining task after 1058 // already started, add an observer to execute the remaining task after
1059 // the end of the initialization. 1059 // the end of the initialization.
1060 AddObserver(new InitialLoadObserver( 1060 AddObserver(new InitialLoadObserver(
1061 this, 1061 this,
1062 base::Bind(&GDataFileSystem::FindEntryByPathOnCallingThread, 1062 base::Bind(&GDataFileSystem::FindEntryByPathSyncOnUIThread,
1063 ui_weak_ptr_, 1063 ui_weak_ptr_,
1064 search_file_path, 1064 search_file_path,
1065 callback))); 1065 callback)));
1066 return; 1066 return;
1067 } else if (root_->origin() == UNINITIALIZED) { 1067 } else if (root_->origin() == UNINITIALIZED) {
1068 // Load root feed from this disk cache. Upon completion, kick off server 1068 // Load root feed from this disk cache. Upon completion, kick off server
1069 // fetching. 1069 // fetching.
1070 root_->set_origin(INITIALIZING); 1070 root_->set_origin(INITIALIZING);
1071 LoadRootFeedFromCache(true, // should_load_from_server 1071 LoadRootFeedFromCache(true, // should_load_from_server
1072 search_file_path, 1072 search_file_path,
1073 callback); 1073 callback);
1074 return; 1074 return;
1075 } else if (root_->NeedsRefresh()) { 1075 } else if (root_->NeedsRefresh()) {
1076 // If content is stale or from disk from cache, fetch content from 1076 // If content is stale or from disk from cache, fetch content from
1077 // the server. 1077 // the server.
1078 ContentOrigin initial_origin = root_->origin(); 1078 ContentOrigin initial_origin = root_->origin();
1079 root_->set_origin(REFRESHING); 1079 root_->set_origin(REFRESHING);
1080 ReloadFeedFromServerIfNeeded(initial_origin, 1080 ReloadFeedFromServerIfNeeded(initial_origin,
1081 root_->largest_changestamp(), 1081 root_->largest_changestamp(),
1082 search_file_path, 1082 search_file_path,
1083 callback); 1083 callback);
1084 return; 1084 return;
1085 } 1085 }
1086 1086
1087 // Post a task to the same thread, rather than calling it here, as 1087 // Post a task to the same thread, rather than calling it here, as
1088 // FindEntryByPathAsync() is asynchronous. 1088 // FindEntryByPathAsync() is asynchronous.
1089 base::MessageLoopProxy::current()->PostTask( 1089 base::MessageLoopProxy::current()->PostTask(
1090 FROM_HERE, 1090 FROM_HERE,
1091 base::Bind(&GDataFileSystem::FindEntryByPathOnCallingThread, 1091 base::Bind(&GDataFileSystem::FindEntryByPathSyncOnUIThread,
1092 ui_weak_ptr_, 1092 ui_weak_ptr_,
1093 search_file_path, 1093 search_file_path,
1094 callback)); 1094 callback));
1095 } 1095 }
1096 1096
1097 void GDataFileSystem::FindEntryByPathOnCallingThread( 1097 void GDataFileSystem::FindEntryByPathSyncOnUIThread(
1098 const FilePath& search_file_path, 1098 const FilePath& search_file_path,
1099 const FindEntryCallback& callback) { 1099 const FindEntryCallback& callback) {
1100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1101
1102 base::AutoLock lock(lock_); // To access root_.
1100 FindEntryCallbackRelayDelegate delegate(callback); 1103 FindEntryCallbackRelayDelegate delegate(callback);
1101 root_->FindEntryByPath(search_file_path, &delegate); 1104 root_->FindEntryByPath(search_file_path, &delegate);
1102 } 1105 }
1103 1106
1104 void GDataFileSystem::ReloadFeedFromServerIfNeeded( 1107 void GDataFileSystem::ReloadFeedFromServerIfNeeded(
1105 ContentOrigin initial_origin, 1108 ContentOrigin initial_origin,
1106 int local_changestamp, 1109 int local_changestamp,
1107 const FilePath& search_file_path, 1110 const FilePath& search_file_path,
1108 const FindEntryCallback& callback) { 1111 const FindEntryCallback& callback) {
1109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1110 1113
1111 // First fetch the latest changestamp to see if there were any new changes 1114 // First fetch the latest changestamp to see if there were any new changes
1112 // there at all. 1115 // there at all.
1113 documents_service_->GetAccountMetadata( 1116 documents_service_->GetAccountMetadata(
1114 base::Bind(&GDataFileSystem::OnGetAccountMetadata, 1117 base::Bind(&GDataFileSystem::OnGetAccountMetadata,
1115 ui_weak_ptr_, 1118 ui_weak_ptr_,
1116 initial_origin, 1119 initial_origin,
1117 local_changestamp, 1120 local_changestamp,
1118 search_file_path, 1121 search_file_path,
1119 callback)); 1122 callback));
1120 } 1123 }
1121 1124
1122 void GDataFileSystem::OnGetAccountMetadata( 1125 void GDataFileSystem::OnGetAccountMetadata(
1123 ContentOrigin initial_origin, 1126 ContentOrigin initial_origin,
1124 int local_changestamp, 1127 int local_changestamp,
1125 const FilePath& search_file_path, 1128 const FilePath& search_file_path,
1126 const FindEntryCallback& callback, 1129 const FindEntryCallback& callback,
1127 GDataErrorCode status, 1130 GDataErrorCode status,
1128 scoped_ptr<base::Value> feed_data) { 1131 scoped_ptr<base::Value> feed_data) {
1132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1133
1129 base::PlatformFileError error = GDataToPlatformError(status); 1134 base::PlatformFileError error = GDataToPlatformError(status);
1130 if (error != base::PLATFORM_FILE_OK) { 1135 if (error != base::PLATFORM_FILE_OK) {
1131 // Get changes starting from the next changestamp from what we have locally. 1136 // Get changes starting from the next changestamp from what we have locally.
1132 LoadFeedFromServer(local_changestamp + 1, 0, search_file_path, callback); 1137 LoadFeedFromServer(local_changestamp + 1, 0, search_file_path, callback);
1133 return; 1138 return;
1134 } 1139 }
1135 1140
1136 scoped_ptr<AccountMetadataFeed> feed; 1141 scoped_ptr<AccountMetadataFeed> feed;
1137 if (feed_data.get()) 1142 if (feed_data.get())
1138 feed = AccountMetadataFeed::CreateFrom(*feed_data); 1143 feed = AccountMetadataFeed::CreateFrom(*feed_data);
(...skipping 14 matching lines...) Expand all
1153 base::AutoLock lock(lock_); 1158 base::AutoLock lock(lock_);
1154 root_->set_origin(initial_origin); 1159 root_->set_origin(initial_origin);
1155 root_->set_refresh_time(base::Time::Now()); 1160 root_->set_refresh_time(base::Time::Now());
1156 } 1161 }
1157 changes_detected = false; 1162 changes_detected = false;
1158 } 1163 }
1159 1164
1160 // No changes detected, continue with search as planned. 1165 // No changes detected, continue with search as planned.
1161 if (!changes_detected) { 1166 if (!changes_detected) {
1162 if (!callback.is_null()) 1167 if (!callback.is_null())
1163 FindEntryByPathOnCallingThread(search_file_path, callback); 1168 FindEntryByPathSyncOnUIThread(search_file_path, callback);
1164 1169
1165 NotifyInitialLoadFinished(); 1170 NotifyInitialLoadFinished();
1166 return; 1171 return;
1167 } 1172 }
1168 1173
1169 SaveFeed(feed_data.Pass(), FilePath(kAccountMetadataFile)); 1174 SaveFeed(feed_data.Pass(), FilePath(kAccountMetadataFile));
1170 1175
1171 // Load changes from the server. 1176 // Load changes from the server.
1172 LoadFeedFromServer(local_changestamp > 0 ? local_changestamp + 1 : 0, 1177 LoadFeedFromServer(local_changestamp > 0 ? local_changestamp + 1 : 0,
1173 feed->largest_changestamp(), 1178 feed->largest_changestamp(),
(...skipping 1510 matching lines...) Expand 10 before | Expand all | Expand 10 after
2684 2689
2685 return; 2690 return;
2686 } 2691 }
2687 2692
2688 // Save file system metadata to disk. 2693 // Save file system metadata to disk.
2689 SaveFileSystemAsProto(); 2694 SaveFileSystemAsProto();
2690 2695
2691 // If we had someone to report this too, then this retrieval was done in a 2696 // If we had someone to report this too, then this retrieval was done in a
2692 // context of search... so continue search. 2697 // context of search... so continue search.
2693 if (!params->callback.is_null()) { 2698 if (!params->callback.is_null()) {
2694 FindEntryByPathOnCallingThread(params->search_file_path, params->callback); 2699 FindEntryByPathSyncOnUIThread(params->search_file_path, params->callback);
2695 } 2700 }
2696 } 2701 }
2697 2702
2698 void GDataFileSystem::LoadRootFeedFromCache( 2703 void GDataFileSystem::LoadRootFeedFromCache(
2699 bool should_load_from_server, 2704 bool should_load_from_server,
2700 const FilePath& search_file_path, 2705 const FilePath& search_file_path,
2701 const FindEntryCallback& callback) { 2706 const FindEntryCallback& callback) {
2702 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2707 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2703 2708
2704 const FilePath path = 2709 const FilePath path =
2705 GetCacheDirectoryPath(GDataRootDirectory::CACHE_TYPE_META).Append( 2710 GetCacheDirectoryPath(GDataRootDirectory::CACHE_TYPE_META).Append(
2706 kFilesystemProtoFile); 2711 kFilesystemProtoFile);
2707 LoadRootFeedParams* params = new LoadRootFeedParams(search_file_path, 2712 LoadRootFeedParams* params = new LoadRootFeedParams(search_file_path,
2708 should_load_from_server, 2713 should_load_from_server,
2709 callback); 2714 callback);
2710 BrowserThread::GetBlockingPool()->PostTaskAndReply(FROM_HERE, 2715 BrowserThread::GetBlockingPool()->PostTaskAndReply(FROM_HERE,
2711 base::Bind(&LoadProtoOnIOThreadPool, path, params), 2716 base::Bind(&LoadProtoOnIOThreadPool, path, params),
2712 base::Bind(&GDataFileSystem::OnProtoLoaded, 2717 base::Bind(&GDataFileSystem::OnProtoLoaded,
2713 ui_weak_ptr_, 2718 ui_weak_ptr_,
2714 base::Owned(params))); 2719 base::Owned(params)));
2715 } 2720 }
2716 2721
2717 void GDataFileSystem::OnProtoLoaded(LoadRootFeedParams* params) { 2722 void GDataFileSystem::OnProtoLoaded(LoadRootFeedParams* params) {
2723 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2724
2718 { 2725 {
2719 base::AutoLock lock(lock_); 2726 base::AutoLock lock(lock_);
2720 // If we have already received updates from the server, bail out. 2727 // If we have already received updates from the server, bail out.
2721 if (root_->origin() == FROM_SERVER) 2728 if (root_->origin() == FROM_SERVER)
2722 return; 2729 return;
2723 } 2730 }
2724 int local_changestamp = 0; 2731 int local_changestamp = 0;
2725 // Update directory structure only if everything is OK and we haven't yet 2732 // Update directory structure only if everything is OK and we haven't yet
2726 // received the feed from the server yet. 2733 // received the feed from the server yet.
2727 if (params->load_error == base::PLATFORM_FILE_OK) { 2734 if (params->load_error == base::PLATFORM_FILE_OK) {
2728 DVLOG(1) << "ParseFromString"; 2735 DVLOG(1) << "ParseFromString";
2729 base::AutoLock lock(lock_); // To access root_. 2736 base::AutoLock lock(lock_); // To access root_.
2730 if (root_->ParseFromString(params->proto)) { 2737 if (root_->ParseFromString(params->proto)) {
2731 root_->set_last_serialized(params->last_modified); 2738 root_->set_last_serialized(params->last_modified);
2732 root_->set_serialized_size(params->proto.size()); 2739 root_->set_serialized_size(params->proto.size());
2733 NotifyInitialLoadFinished(); 2740 NotifyInitialLoadFinished();
2734 local_changestamp = root_->largest_changestamp(); 2741 local_changestamp = root_->largest_changestamp();
2735 } else { 2742 } else {
2736 params->load_error = base::PLATFORM_FILE_ERROR_FAILED; 2743 params->load_error = base::PLATFORM_FILE_ERROR_FAILED;
2737 LOG(WARNING) << "Parse of cached proto file failed"; 2744 LOG(WARNING) << "Parse of cached proto file failed";
2738 } 2745 }
2739 } 2746 }
2740 2747
2741 FindEntryCallback callback = params->callback; 2748 FindEntryCallback callback = params->callback;
2742 // If we got feed content from cache, try search over it. 2749 // If we got feed content from cache, try search over it.
2743 if (!params->should_load_from_server || 2750 if (!params->should_load_from_server ||
2744 (params->load_error == base::PLATFORM_FILE_OK && !callback.is_null())) { 2751 (params->load_error == base::PLATFORM_FILE_OK && !callback.is_null())) {
2745 // Continue file content search operation if the delegate hasn't terminated 2752 // Continue file content search operation if the delegate hasn't terminated
2746 // this search branch already. 2753 // this search branch already.
2747 FindEntryByPathOnCallingThread(params->search_file_path, callback); 2754 FindEntryByPathSyncOnUIThread(params->search_file_path, callback);
2748 callback.Reset(); 2755 callback.Reset();
2749 } 2756 }
2750 2757
2751 if (!params->should_load_from_server) 2758 if (!params->should_load_from_server)
2752 return; 2759 return;
2753 2760
2754 { 2761 {
2755 base::AutoLock lock(lock_); 2762 base::AutoLock lock(lock_);
2756 if (root_->origin() != INITIALIZING) 2763 if (root_->origin() != INITIALIZING)
2757 root_->set_origin(REFRESHING); 2764 root_->set_origin(REFRESHING);
(...skipping 1957 matching lines...) Expand 10 before | Expand all | Expand 10 after
4715 pref_registrar_->Init(profile_->GetPrefs()); 4722 pref_registrar_->Init(profile_->GetPrefs());
4716 pref_registrar_->Add(prefs::kDisableGDataHostedFiles, this); 4723 pref_registrar_->Add(prefs::kDisableGDataHostedFiles, this);
4717 } 4724 }
4718 4725
4719 void SetFreeDiskSpaceGetterForTesting(FreeDiskSpaceGetterInterface* getter) { 4726 void SetFreeDiskSpaceGetterForTesting(FreeDiskSpaceGetterInterface* getter) {
4720 delete global_free_disk_getter_for_testing; // Safe to delete NULL; 4727 delete global_free_disk_getter_for_testing; // Safe to delete NULL;
4721 global_free_disk_getter_for_testing = getter; 4728 global_free_disk_getter_for_testing = getter;
4722 } 4729 }
4723 4730
4724 } // namespace gdata 4731 } // namespace gdata
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/gdata/gdata_file_system.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698