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

Unified Diff: components/sync_sessions/synced_session_tracker.cc

Issue 1877083002: [Sync] Moved tab_node_id tracking to session object and improved foreign session garbage collection. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: components/sync_sessions/synced_session_tracker.cc
diff --git a/components/sync_sessions/synced_session_tracker.cc b/components/sync_sessions/synced_session_tracker.cc
index 5dbcf146f5579c063071a5fa69ee6951f99f895c..722252728dc6b1d1a92b02ef0bbb8019184a1bf2 100644
--- a/components/sync_sessions/synced_session_tracker.cc
+++ b/components/sync_sessions/synced_session_tracker.cc
@@ -28,8 +28,35 @@ bool ShouldSyncSessionWindow(sync_sessions::SyncSessionsClient* sessions_client,
return false;
}
+// To be presentable it means you must have windows with tabs with syncable
Nicolas Zea 2016/04/12 20:38:03 "To be presentable it means you must have windows
skym 2016/04/12 22:12:14 Done.
+// content.
+bool IsPresentable(sync_sessions::SyncSessionsClient* sessions_client,
+ sync_driver::SyncedSession* foreign_session) {
+ for (sync_driver::SyncedSession::SyncedWindowMap::const_iterator iter =
+ foreign_session->windows.begin();
+ iter != foreign_session->windows.end(); ++iter) {
+ if (ShouldSyncSessionWindow(sessions_client, *(iter->second))) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace
+SyncedSessionTracker::SessionTabWrapper::SessionTabWrapper()
+ : tab_ptr(NULL), owned(false) {}
+
+SyncedSessionTracker::SessionTabWrapper::SessionTabWrapper(
+ sessions::SessionTab* tab_ptr,
+ OwnedState owned,
+ int tab_node_id)
+ : tab_ptr(tab_ptr), owned(owned == IS_OWNED) {
+ tab_node_ids.insert(tab_node_id);
+}
+
+SyncedSessionTracker::SessionTabWrapper::~SessionTabWrapper() {}
+
SyncedSessionTracker::SyncedSessionTracker(
sync_sessions::SyncSessionsClient* sessions_client)
: sessions_client_(sessions_client) {}
@@ -44,29 +71,18 @@ void SyncedSessionTracker::SetLocalSessionTag(
}
bool SyncedSessionTracker::LookupAllForeignSessions(
- std::vector<const sync_driver::SyncedSession*>* sessions) const {
+ std::vector<const sync_driver::SyncedSession*>* sessions,
+ bool presentable) const {
DCHECK(sessions);
sessions->clear();
- // Fill vector of sessions from our synced session map.
for (SyncedSessionMap::const_iterator i = synced_session_map_.begin();
i != synced_session_map_.end(); ++i) {
- // Only include foreign sessions with open tabs.
sync_driver::SyncedSession* foreign_session = i->second;
- if (i->first != local_session_tag_ && !foreign_session->windows.empty()) {
- bool found_tabs = false;
- for (sync_driver::SyncedSession::SyncedWindowMap::const_iterator iter =
- foreign_session->windows.begin();
- iter != foreign_session->windows.end(); ++iter) {
- if (ShouldSyncSessionWindow(sessions_client_, *(iter->second))) {
- found_tabs = true;
- break;
- }
- }
- if (found_tabs)
- sessions->push_back(foreign_session);
+ if (i->first != local_session_tag_ &&
+ (!presentable || IsPresentable(sessions_client_, foreign_session))) {
+ sessions->push_back(foreign_session);
}
}
-
return !sessions->empty();
}
@@ -95,14 +111,14 @@ bool SyncedSessionTracker::LookupSessionTab(
SyncedTabMap::const_iterator tab_map_iter = synced_tab_map_.find(tag);
if (tab_map_iter == synced_tab_map_.end()) {
// We have no record of this session.
- *tab = NULL;
+ *tab = nullptr;
return false;
}
IDToSessionTabMap::const_iterator tab_iter =
tab_map_iter->second.find(tab_id);
if (tab_iter == tab_map_iter->second.end()) {
// We have no record of this tab.
- *tab = NULL;
+ *tab = nullptr;
return false;
}
*tab = tab_iter->second.tab_ptr;
@@ -113,15 +129,20 @@ bool SyncedSessionTracker::LookupTabNodeIds(const std::string& session_tag,
std::set<int>* tab_node_ids) {
tab_node_ids->clear();
SyncedTabMap::const_iterator tab_map_iter = synced_tab_map_.find(session_tag);
- if (tab_map_iter == synced_tab_map_.end())
+ if (tab_map_iter == synced_tab_map_.end()) {
Nicolas Zea 2016/04/12 20:38:03 nit: single line if body
skym 2016/04/12 22:12:14 Method has changed significantly.
return false;
+ }
IDToSessionTabMap::const_iterator tab_iter = tab_map_iter->second.begin();
while (tab_iter != tab_map_iter->second.end()) {
- if (tab_iter->second.tab_node_id != TabNodePool::kInvalidTabNodeID)
- tab_node_ids->insert(tab_iter->second.tab_node_id);
+ tab_node_ids->insert(tab_iter->second.tab_node_ids.begin(),
+ tab_iter->second.tab_node_ids.end());
++tab_iter;
}
+
+ // Incase an invalid node id was included, remove it.
+ tab_node_ids->erase(TabNodePool::kInvalidTabNodeID);
+
return true;
}
@@ -153,23 +174,29 @@ sync_driver::SyncedSession* SyncedSessionTracker::GetSession(
}
bool SyncedSessionTracker::DeleteSession(const std::string& session_tag) {
- bool found_session = false;
+ // Cleanup first, we need to check every wrapper and remove model objects
+ // if the parent session isn't going to delete in it's destructor.
+ CleanupSession(session_tag);
+
+ bool header_existed = false;
SyncedSessionMap::iterator iter = synced_session_map_.find(session_tag);
if (iter != synced_session_map_.end()) {
sync_driver::SyncedSession* session = iter->second;
+ // An implicitly created session that has children tabs but no header node
+ // will have never had the device_type changed from unset.
+ header_existed =
+ session->device_type != sync_driver::SyncedSession::TYPE_UNSET;
synced_session_map_.erase(iter);
// SyncedSession's destructor will trigger deletion of windows which will in
- // turn trigger the deletion of tabs. This doens't affect wrappers.
+ // turn trigger the deletion of tabs. This doesn't affect wrappers.
delete session;
- found_session = true;
}
+
// These two erase(...) calls only affect the wrappers.
synced_window_map_.erase(session_tag);
- // It's possible there was no header node but there were tab nodes.
- if (synced_tab_map_.erase(session_tag) > 0) {
- found_session = true;
- }
- return found_session;
+ synced_tab_map_.erase(session_tag);
+
+ return header_existed;
}
void SyncedSessionTracker::ResetSessionTracking(
@@ -198,8 +225,29 @@ void SyncedSessionTracker::ResetSessionTracking(
}
}
+void SyncedSessionTracker::TryDeleteTab(const std::string& session_tag,
+ SessionID::id_type tab_id,
+ int tab_node_id) {
+ SyncedTabMap::iterator tab_map_iter = synced_tab_map_.find(session_tag);
+ if (tab_map_iter != synced_tab_map_.end()) {
+ IDToSessionTabMap::iterator tab_iter = tab_map_iter->second.find(tab_id);
+ if (tab_iter != tab_map_iter->second.end()) {
+ // Scrub any occurrence of |tab_node_id| first to make verifying if we
+ // should actually delete easier.
+ tab_iter->second.tab_node_ids.erase(tab_node_id);
+
+ // Try to delete the tab if it no longer holds valid tab node ids and it's
+ // an orphan.
+ if (tab_iter->second.tab_node_ids.empty() &&
+ DeleteOldSessionTabIfNecessary(tab_iter->second)) {
+ tab_map_iter->second.erase(tab_iter);
+ }
+ }
+ }
+}
+
bool SyncedSessionTracker::DeleteOldSessionWindowIfNecessary(
- SessionWindowWrapper window_wrapper) {
+ const SessionWindowWrapper& window_wrapper) {
if (!window_wrapper.owned) {
DVLOG(1) << "Deleting closed window "
<< window_wrapper.window_ptr->window_id.id();
@@ -213,7 +261,7 @@ bool SyncedSessionTracker::DeleteOldSessionWindowIfNecessary(
}
bool SyncedSessionTracker::DeleteOldSessionTabIfNecessary(
- SessionTabWrapper tab_wrapper) {
+ const SessionTabWrapper& tab_wrapper) {
if (!tab_wrapper.owned) {
if (VLOG_IS_ON(1)) {
sessions::SessionTab* tab_ptr = tab_wrapper.tab_ptr;
@@ -265,7 +313,7 @@ void SyncedSessionTracker::CleanupSession(const std::string& session_tag) {
void SyncedSessionTracker::PutWindowInSession(const std::string& session_tag,
SessionID::id_type window_id) {
- sessions::SessionWindow* window_ptr = NULL;
+ sessions::SessionWindow* window_ptr = nullptr;
IDToSessionWindowMap::iterator iter =
synced_window_map_[session_tag].find(window_id);
if (iter != synced_window_map_[session_tag].end()) {
@@ -306,10 +354,6 @@ void SyncedSessionTracker::PutTabInWindow(const std::string& session_tag,
// We know that we will eventually process (via GetTab) every single tab node
// in the system, so we permit ourselves to use kInvalidTabNodeID here and
// rely on the later update to build the mapping (or a restart).
- // TODO(tim): Bug 98892. Update comment when Sync API conversion finishes to
- // mention that in the meantime, the only ill effect is that we may not be
- // able to fully clean up a stale foreign session, but it will get garbage
- // collected eventually.
sessions::SessionTab* tab_ptr =
GetTabImpl(session_tag, tab_id, TabNodePool::kInvalidTabNodeID);
@@ -338,7 +382,7 @@ void SyncedSessionTracker::PutTabInWindow(const std::string& session_tag,
std::vector<sessions::SessionTab*>& window_tabs =
GetSession(session_tag)->windows[window_id]->tabs;
if (window_tabs.size() <= tab_index) {
- window_tabs.resize(tab_index + 1, NULL);
+ window_tabs.resize(tab_index + 1, nullptr);
}
DCHECK(!window_tabs[tab_index]);
window_tabs[tab_index] = tab_ptr;
@@ -356,7 +400,7 @@ sessions::SessionTab* SyncedSessionTracker::GetTabImpl(
const std::string& session_tag,
SessionID::id_type tab_id,
int tab_node_id) {
- sessions::SessionTab* tab_ptr = NULL;
+ sessions::SessionTab* tab_ptr = nullptr;
IDToSessionTabMap::iterator iter = synced_tab_map_[session_tag].find(tab_id);
if (iter != synced_tab_map_[session_tag].end()) {
tab_ptr = iter->second.tab_ptr;
@@ -381,8 +425,8 @@ sessions::SessionTab* SyncedSessionTracker::GetTabImpl(
// the tab itself, so the tab node id wasn't available at the time and
// is currenlty kInvalidTabNodeID.
//
- // In both cases, we update the tab_node_id.
- iter->second.tab_node_id = tab_node_id;
+ // In both cases, we can safely throw it into the set of node ids.
+ iter->second.tab_node_ids.insert(tab_node_id);
}
if (VLOG_IS_ON(1)) {
@@ -416,6 +460,12 @@ sessions::SessionTab* SyncedSessionTracker::GetTabImpl(
}
void SyncedSessionTracker::Clear() {
+ // Cleanup unowned things first, before we let SyncedSession's destructor take
+ // care of everything else.
+ for (const auto& kv : synced_session_map_) {
+ CleanupSession(kv.first);
+ }
+
// Delete SyncedSession objects (which also deletes all their windows/tabs).
STLDeleteValues(&synced_session_map_);

Powered by Google App Engine
This is Rietveld 408576698