Index: net/cookies/cookie_monster.cc |
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc |
index c5be7c4cd450a93875e6d8a2963f412a69d17be2..01513f98194a66c73866dd1569b50ebf0eed8b08 100644 |
--- a/net/cookies/cookie_monster.cc |
+++ b/net/cookies/cookie_monster.cc |
@@ -344,7 +344,8 @@ CookieMonster::CookieMonster(PersistentCookieStore* store, |
last_access_threshold_milliseconds)), |
delegate_(delegate), |
last_statistic_record_time_(base::Time::Now()), |
- persist_session_cookies_(false) { |
+ persist_session_cookies_(false), |
+ weak_ptr_factory_(this) { |
InitializeHistograms(); |
cookieable_schemes_.insert( |
cookieable_schemes_.begin(), kDefaultCookieableSchemes, |
@@ -364,51 +365,23 @@ class CookieMonster::CookieMonsterTask |
explicit CookieMonsterTask(CookieMonster* cookie_monster); |
virtual ~CookieMonsterTask(); |
- // Invokes the callback immediately, if the current thread is the one |
- // that originated the task, or queues the callback for execution on the |
- // appropriate thread. Maintains a reference to this CookieMonsterTask |
- // instance until the callback completes. |
- void InvokeCallback(base::Closure callback); |
- |
CookieMonster* cookie_monster() { return cookie_monster_; } |
private: |
friend class base::RefCountedThreadSafe<CookieMonsterTask>; |
CookieMonster* cookie_monster_; |
- scoped_refptr<base::SingleThreadTaskRunner> thread_; |
DISALLOW_COPY_AND_ASSIGN(CookieMonsterTask); |
}; |
CookieMonster::CookieMonsterTask::CookieMonsterTask( |
CookieMonster* cookie_monster) |
- : cookie_monster_(cookie_monster), |
- thread_(base::ThreadTaskRunnerHandle::Get()) { |
-} |
+ : cookie_monster_(cookie_monster) {} |
CookieMonster::CookieMonsterTask::~CookieMonsterTask() { |
} |
-// Unfortunately, one cannot re-bind a Callback with parameters into a closure. |
-// Therefore, the closure passed to InvokeCallback is a clumsy binding of |
-// Callback::Run on a wrapped Callback instance. Since Callback is not |
-// reference counted, we bind to an instance that is a member of the |
-// CookieMonsterTask subclass. Then, we cannot simply post the callback to a |
-// message loop because the underlying instance may be destroyed (along with the |
-// CookieMonsterTask instance) in the interim. Therefore, we post a callback |
-// bound to the CookieMonsterTask, which *is* reference counted (thus preventing |
-// destruction of the original callback), and which invokes the closure (which |
-// invokes the original callback with the returned data). |
-void CookieMonster::CookieMonsterTask::InvokeCallback(base::Closure callback) { |
- if (thread_->BelongsToCurrentThread()) { |
- callback.Run(); |
- } else { |
- thread_->PostTask(FROM_HERE, base::Bind(&CookieMonsterTask::InvokeCallback, |
- this, callback)); |
- } |
-} |
- |
// Task class for SetCookieWithDetails call. |
class CookieMonster::SetCookieWithDetailsTask : public CookieMonsterTask { |
public: |
@@ -473,10 +446,8 @@ void CookieMonster::SetCookieWithDetailsTask::Run() { |
url_, name_, value_, domain_, path_, creation_time_, expiration_time_, |
last_access_time_, secure_, http_only_, same_site_, |
enforce_strict_secure_, priority_); |
- if (!callback_.is_null()) { |
- this->InvokeCallback(base::Bind(&SetCookiesCallback::Run, |
- base::Unretained(&callback_), success)); |
- } |
+ if (!callback_.is_null()) |
+ callback_.Run(success); |
} |
// Task class for GetAllCookies call. |
@@ -501,8 +472,7 @@ class CookieMonster::GetAllCookiesTask : public CookieMonsterTask { |
void CookieMonster::GetAllCookiesTask::Run() { |
if (!callback_.is_null()) { |
CookieList cookies = this->cookie_monster()->GetAllCookies(); |
- this->InvokeCallback(base::Bind(&GetCookieListCallback::Run, |
- base::Unretained(&callback_), cookies)); |
+ callback_.Run(cookies); |
} |
} |
@@ -536,8 +506,7 @@ void CookieMonster::GetCookieListWithOptionsTask::Run() { |
if (!callback_.is_null()) { |
CookieList cookies = |
this->cookie_monster()->GetCookieListWithOptions(url_, options_); |
- this->InvokeCallback(base::Bind(&GetCookieListCallback::Run, |
- base::Unretained(&callback_), cookies)); |
+ callback_.Run(cookies); |
} |
} |
@@ -568,8 +537,11 @@ class CookieMonster::DeleteTask : public CookieMonsterTask { |
private: |
// Runs the delete task and returns a result. |
virtual Result RunDeleteTask() = 0; |
+ // Runs the delete task and then returns a callback to be called after |
+ // flushing the persistent store. |
+ // TODO(mmenke): This seems like a pretty ugly and needlessly confusing API. |
+ // Simplify it? |
base::Closure RunDeleteTaskAndBindCallback(); |
Mike West
2016/03/01 13:59:28
I'd suggest doing so, but in a separate CL. No nee
|
- void FlushDone(const base::Closure& callback); |
typename CallbackType<Result>::Type callback_; |
@@ -597,16 +569,13 @@ base::Closure CookieMonster::DeleteTask<void>::RunDeleteTaskAndBindCallback() { |
template <typename Result> |
void CookieMonster::DeleteTask<Result>::Run() { |
- this->cookie_monster()->FlushStore(base::Bind( |
- &DeleteTask<Result>::FlushDone, this, RunDeleteTaskAndBindCallback())); |
-} |
- |
-template <typename Result> |
-void CookieMonster::DeleteTask<Result>::FlushDone( |
- const base::Closure& callback) { |
+ base::Closure callback = RunDeleteTaskAndBindCallback(); |
if (!callback.is_null()) { |
- this->InvokeCallback(callback); |
+ callback = base::Bind( |
+ &CookieMonster::RunCallback, |
+ this->cookie_monster()->weak_ptr_factory_.GetWeakPtr(), callback); |
} |
+ this->cookie_monster()->FlushStore(callback); |
} |
// Task class for DeleteAllCreatedBetween call. |
@@ -727,10 +696,8 @@ class CookieMonster::SetCookieWithOptionsTask : public CookieMonsterTask { |
void CookieMonster::SetCookieWithOptionsTask::Run() { |
bool result = this->cookie_monster()->SetCookieWithOptions(url_, cookie_line_, |
options_); |
- if (!callback_.is_null()) { |
- this->InvokeCallback(base::Bind(&SetCookiesCallback::Run, |
- base::Unretained(&callback_), result)); |
- } |
+ if (!callback_.is_null()) |
+ callback_.Run(result); |
} |
// Task class for SetAllCookies call. |
@@ -770,10 +737,8 @@ void CookieMonster::SetAllCookiesTask::Run() { |
if (positive_diff.size() > 0) |
result = this->cookie_monster()->SetCanonicalCookies(list_); |
- if (!callback_.is_null()) { |
- this->InvokeCallback(base::Bind(&SetCookiesCallback::Run, |
- base::Unretained(&callback_), result)); |
- } |
+ if (!callback_.is_null()) |
+ callback_.Run(result); |
} |
// Task class for GetCookiesWithOptions call. |
@@ -809,10 +774,8 @@ void CookieMonster::GetCookiesWithOptionsTask::Run() { |
"456373 CookieMonster::GetCookiesWithOptionsTask::Run")); |
std::string cookie = |
this->cookie_monster()->GetCookiesWithOptions(url_, options_); |
- if (!callback_.is_null()) { |
- this->InvokeCallback(base::Bind(&GetCookiesCallback::Run, |
- base::Unretained(&callback_), cookie)); |
- } |
+ if (!callback_.is_null()) |
+ callback_.Run(cookie); |
} |
// Task class for DeleteCookie call. |
@@ -889,7 +852,7 @@ void CookieMonster::SetCookieWithDetailsAsync( |
} |
void CookieMonster::FlushStore(const base::Closure& callback) { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
if (initialized_ && store_.get()) |
store_->Flush(callback); |
else if (!callback.is_null()) |
@@ -897,6 +860,7 @@ void CookieMonster::FlushStore(const base::Closure& callback) { |
} |
void CookieMonster::SetForceKeepSessionState() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
if (store_) |
store_->SetForceKeepSessionState(); |
} |
@@ -994,7 +958,7 @@ void CookieMonster::DeleteSessionCookiesAsync( |
void CookieMonster::SetCookieableSchemes( |
const std::vector<std::string>& schemes) { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
// Calls to this method will have no effect if made after a WebView or |
// CookieManager instance has been created. |
@@ -1006,12 +970,13 @@ void CookieMonster::SetCookieableSchemes( |
// This function must be called before the CookieMonster is used. |
void CookieMonster::SetPersistSessionCookies(bool persist_session_cookies) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(!initialized_); |
persist_session_cookies_ = persist_session_cookies; |
} |
bool CookieMonster::IsCookieableScheme(const std::string& scheme) { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
return std::find(cookieable_schemes_.begin(), cookieable_schemes_.end(), |
scheme) != cookieable_schemes_.end(); |
@@ -1026,7 +991,7 @@ scoped_ptr<CookieStore::CookieChangedSubscription> |
CookieMonster::AddCallbackForCookie(const GURL& gurl, |
const std::string& name, |
const CookieChangedCallback& callback) { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
std::pair<GURL, std::string> key(gurl, name); |
if (hook_map_.count(key) == 0) |
hook_map_[key] = make_linked_ptr(new CookieChangedCallbackList()); |
@@ -1035,11 +1000,8 @@ CookieMonster::AddCallbackForCookie(const GURL& gurl, |
} |
CookieMonster::~CookieMonster() { |
- // Clean up cookies |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
- // InternalDeleteCookie expects the lock to be held, even though there can be |
- // no contention here. |
- base::AutoLock autolock(lock_); |
for (CookieMap::iterator cookie_it = cookies_.begin(); |
cookie_it != cookies_.end();) { |
CookieMap::iterator current_cookie_it = cookie_it; |
@@ -1062,7 +1024,7 @@ bool CookieMonster::SetCookieWithDetails(const GURL& url, |
bool same_site, |
bool enforce_strict_secure, |
CookiePriority priority) { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
if (!HasCookieableScheme(url)) |
return false; |
@@ -1096,7 +1058,7 @@ bool CookieMonster::SetCookieWithDetails(const GURL& url, |
} |
CookieList CookieMonster::GetAllCookies() { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
// This function is being called to scrape the cookie list for management UI |
// or similar. We shouldn't show expired cookies in this list since it will |
@@ -1129,7 +1091,7 @@ CookieList CookieMonster::GetAllCookies() { |
CookieList CookieMonster::GetCookieListWithOptions( |
const GURL& url, |
const CookieOptions& options) { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
CookieList cookies; |
if (!HasCookieableScheme(url)) |
@@ -1149,7 +1111,7 @@ CookieList CookieMonster::GetCookieListWithOptions( |
int CookieMonster::DeleteAllCreatedBetween(const Time& delete_begin, |
const Time& delete_end) { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
int num_deleted = 0; |
for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) { |
@@ -1171,7 +1133,7 @@ int CookieMonster::DeleteAllCreatedBetween(const Time& delete_begin, |
int CookieMonster::DeleteAllCreatedBetweenForHost(const Time delete_begin, |
const Time delete_end, |
const GURL& url) { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
if (!HasCookieableScheme(url)) |
return 0; |
@@ -1207,7 +1169,7 @@ int CookieMonster::DeleteAllCreatedBetweenForHost(const Time delete_begin, |
bool CookieMonster::SetCookieWithOptions(const GURL& url, |
const std::string& cookie_line, |
const CookieOptions& options) { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
if (!HasCookieableScheme(url)) { |
return false; |
@@ -1218,7 +1180,7 @@ bool CookieMonster::SetCookieWithOptions(const GURL& url, |
std::string CookieMonster::GetCookiesWithOptions(const GURL& url, |
const CookieOptions& options) { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
if (!HasCookieableScheme(url)) |
return std::string(); |
@@ -1236,7 +1198,7 @@ std::string CookieMonster::GetCookiesWithOptions(const GURL& url, |
void CookieMonster::DeleteCookie(const GURL& url, |
const std::string& cookie_name) { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
if (!HasCookieableScheme(url)) |
return; |
@@ -1268,7 +1230,7 @@ void CookieMonster::DeleteCookie(const GURL& url, |
} |
int CookieMonster::DeleteCanonicalCookie(const CanonicalCookie& cookie) { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
for (CookieMapItPair its = cookies_.equal_range(GetKey(cookie.Domain())); |
its.first != its.second; ++its.first) { |
@@ -1284,8 +1246,8 @@ int CookieMonster::DeleteCanonicalCookie(const CanonicalCookie& cookie) { |
bool CookieMonster::SetCookieWithCreationTime(const GURL& url, |
const std::string& cookie_line, |
const base::Time& creation_time) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(!store_.get()) << "This method is only to be used by unit-tests."; |
- base::AutoLock autolock(lock_); |
if (!HasCookieableScheme(url)) { |
return false; |
@@ -1300,7 +1262,7 @@ bool CookieMonster::SetCookieWithCreationTime(const GURL& url, |
} |
int CookieMonster::DeleteSessionCookies() { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
int num_deleted = 0; |
for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) { |
@@ -1319,10 +1281,12 @@ int CookieMonster::DeleteSessionCookies() { |
} |
void CookieMonster::MarkCookieStoreAsInitialized() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
initialized_ = true; |
} |
void CookieMonster::FetchAllCookiesIfNecessary() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
if (store_.get() && !started_fetching_all_cookies_) { |
started_fetching_all_cookies_ = true; |
FetchAllCookies(); |
@@ -1330,16 +1294,20 @@ void CookieMonster::FetchAllCookiesIfNecessary() { |
} |
void CookieMonster::FetchAllCookies() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(store_.get()) << "Store must exist to initialize"; |
DCHECK(!finished_fetching_all_cookies_) |
<< "All cookies have already been fetched."; |
// We bind in the current time so that we can report the wall-clock time for |
// loading cookies. |
- store_->Load(base::Bind(&CookieMonster::OnLoaded, this, TimeTicks::Now())); |
+ store_->Load(base::Bind(&CookieMonster::OnLoaded, |
+ weak_ptr_factory_.GetWeakPtr(), TimeTicks::Now())); |
} |
bool CookieMonster::ShouldFetchAllCookiesWhenFetchingAnyCookie() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
if (fetch_strategy_ == kUnknownFetch) { |
const std::string group_name = |
base::FieldTrialList::FindFullName(kCookieMonsterFetchStrategyName); |
@@ -1359,6 +1327,7 @@ bool CookieMonster::ShouldFetchAllCookiesWhenFetchingAnyCookie() { |
void CookieMonster::OnLoaded(TimeTicks beginning_time, |
const std::vector<CanonicalCookie*>& cookies) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
StoreLoadedCookies(cookies); |
histogram_time_blocked_on_load_->AddTime(TimeTicks::Now() - beginning_time); |
@@ -1368,52 +1337,47 @@ void CookieMonster::OnLoaded(TimeTicks beginning_time, |
void CookieMonster::OnKeyLoaded(const std::string& key, |
const std::vector<CanonicalCookie*>& cookies) { |
- // This function does its own separate locking. |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
StoreLoadedCookies(cookies); |
- std::deque<scoped_refptr<CookieMonsterTask>> tasks_pending_for_key; |
+ auto tasks_pending_for_key = tasks_pending_for_key_.find(key); |
- // We need to do this repeatedly until no more tasks were added to the queue |
- // during the period where we release the lock. |
- while (true) { |
- { |
- base::AutoLock autolock(lock_); |
- std::map<std::string, |
- std::deque<scoped_refptr<CookieMonsterTask>>>::iterator it = |
- tasks_pending_for_key_.find(key); |
- if (it == tasks_pending_for_key_.end()) { |
- keys_loaded_.insert(key); |
- return; |
- } |
- if (it->second.empty()) { |
- keys_loaded_.insert(key); |
- tasks_pending_for_key_.erase(it); |
- return; |
- } |
- it->second.swap(tasks_pending_for_key); |
- } |
+ // TODO(mmenke): Can this be turned into a DCHECK? |
Mike West
2016/03/01 13:59:28
I think so. There shouldn't be any case in which w
mmenke
2016/03/01 16:03:45
My CL to re-order things may change that property
|
+ if (tasks_pending_for_key == tasks_pending_for_key_.end()) |
+ return; |
- while (!tasks_pending_for_key.empty()) { |
- scoped_refptr<CookieMonsterTask> task = tasks_pending_for_key.front(); |
- task->Run(); |
- tasks_pending_for_key.pop_front(); |
- } |
+ // Run all tasks for the key. Note that running a task can result it multiple |
Mike West
2016/03/01 13:59:28
Nit: s/it multiple/in multiple/
mmenke
2016/03/01 16:03:45
Done.
|
+ // tasks being added to the back of the deque. |
+ while (!tasks_pending_for_key->second.empty()) { |
+ // Removing a task from the deque before running it isn't strictly |
+ // necessary, but just seems like a good idea. |
Mike West
2016/03/01 13:59:28
Nit: I'd drop the comment. I'd agree that it's a g
mmenke
2016/03/01 16:03:45
Done.
|
+ scoped_refptr<CookieMonsterTask> task = |
+ tasks_pending_for_key->second.front(); |
+ tasks_pending_for_key->second.pop_front(); |
+ |
+ task->Run(); |
} |
+ |
+ tasks_pending_for_key_.erase(tasks_pending_for_key); |
+ |
+ // This has to be done last, in case running a task queues a new task for the |
+ // key, to ensure tasks are run in the correct order. |
+ keys_loaded_.insert(key); |
} |
void CookieMonster::StoreLoadedCookies( |
const std::vector<CanonicalCookie*>& cookies) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
// TODO(erikwright): Remove ScopedTracker below once crbug.com/457528 is |
// fixed. |
tracked_objects::ScopedTracker tracking_profile( |
FROM_HERE_WITH_EXPLICIT_FUNCTION( |
"457528 CookieMonster::StoreLoadedCookies")); |
- // Initialize the store and sync in any saved persistent cookies. We don't |
- // care if it's expired, insert it so it can be garbage collected, removed, |
- // and sync'd. |
- base::AutoLock autolock(lock_); |
Mike West
2016/03/01 13:59:28
Appropos of nothing, I really like seeing all thes
|
- |
+ // Even if a key is expired, insert it so it can be garbage collected, |
+ // removed, and sync'd. |
CookieItVector cookies_with_control_chars; |
for (std::vector<CanonicalCookie*>::const_iterator it = cookies.begin(); |
@@ -1466,25 +1430,21 @@ void CookieMonster::StoreLoadedCookies( |
} |
void CookieMonster::InvokeQueue() { |
- while (true) { |
- scoped_refptr<CookieMonsterTask> request_task; |
- { |
- base::AutoLock autolock(lock_); |
- if (tasks_pending_.empty()) { |
- finished_fetching_all_cookies_ = true; |
- creation_times_.clear(); |
- keys_loaded_.clear(); |
- break; |
- } |
- request_task = tasks_pending_.front(); |
- tasks_pending_.pop(); |
- } |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
+ while (!tasks_pending_.empty()) { |
+ scoped_refptr<CookieMonsterTask> request_task = tasks_pending_.front(); |
+ tasks_pending_.pop(); |
request_task->Run(); |
} |
+ |
+ finished_fetching_all_cookies_ = true; |
+ creation_times_.clear(); |
+ keys_loaded_.clear(); |
} |
void CookieMonster::EnsureCookiesMapIsValid() { |
- lock_.AssertAcquired(); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
// Iterate through all the of the cookies, grouped by host. |
CookieMap::iterator prev_range_end = cookies_.begin(); |
@@ -1502,7 +1462,7 @@ void CookieMonster::EnsureCookiesMapIsValid() { |
void CookieMonster::TrimDuplicateCookiesForKey(const std::string& key, |
CookieMap::iterator begin, |
CookieMap::iterator end) { |
- lock_.AssertAcquired(); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
// Set of cookies ordered by creation time. |
typedef std::set<CookieMap::iterator, OrderByCreationTimeDesc> CookieSet; |
@@ -1578,7 +1538,7 @@ void CookieMonster::FindCookiesForHostAndDomain( |
const GURL& url, |
const CookieOptions& options, |
std::vector<CanonicalCookie*>* cookies) { |
- lock_.AssertAcquired(); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
const Time current_time(CurrentTime()); |
@@ -1597,7 +1557,7 @@ void CookieMonster::FindCookiesForKey(const std::string& key, |
const CookieOptions& options, |
const Time& current, |
std::vector<CanonicalCookie*>* cookies) { |
- lock_.AssertAcquired(); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
for (CookieMapItPair its = cookies_.equal_range(key); |
its.first != its.second;) { |
@@ -1631,7 +1591,7 @@ bool CookieMonster::DeleteAnyEquivalentCookie(const std::string& key, |
bool skip_httponly, |
bool already_expired, |
bool enforce_strict_secure) { |
- lock_.AssertAcquired(); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
bool found_equivalent_cookie = false; |
bool skipped_httponly = false; |
@@ -1694,11 +1654,12 @@ CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie( |
const std::string& key, |
CanonicalCookie* cc, |
bool sync_to_store) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
// TODO(mkwst): Remove ScopedTracker below once crbug.com/456373 is fixed. |
tracked_objects::ScopedTracker tracking_profile( |
FROM_HERE_WITH_EXPLICIT_FUNCTION( |
"456373 CookieMonster::InternalInsertCookie")); |
- lock_.AssertAcquired(); |
if ((cc->IsPersistent() || persist_session_cookies_) && store_.get() && |
sync_to_store) |
@@ -1736,7 +1697,7 @@ CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie( |
histogram_cookie_source_scheme_->Add(cookie_source_sample); |
} |
- RunCallbacks(*cc, false); |
+ RunCookieChangedCallbacks(*cc, false); |
return inserted; |
} |
@@ -1746,7 +1707,7 @@ bool CookieMonster::SetCookieWithCreationTimeAndOptions( |
const std::string& cookie_line, |
const Time& creation_time_or_null, |
const CookieOptions& options) { |
- lock_.AssertAcquired(); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
VLOG(kVlogSetCookies) << "SetCookie() line: " << cookie_line; |
@@ -1768,6 +1729,8 @@ bool CookieMonster::SetCookieWithCreationTimeAndOptions( |
bool CookieMonster::SetCanonicalCookie(scoped_ptr<CanonicalCookie> cc, |
const CookieOptions& options) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
Time creation_time = cc->CreationDate(); |
const std::string key(GetKey(cc->Domain())); |
bool already_expired = cc->IsExpired(creation_time); |
@@ -1816,7 +1779,7 @@ bool CookieMonster::SetCanonicalCookie(scoped_ptr<CanonicalCookie> cc, |
} |
bool CookieMonster::SetCanonicalCookies(const CookieList& list) { |
- base::AutoLock autolock(lock_); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
CookieOptions options; |
options.set_include_httponly(); |
@@ -1833,7 +1796,7 @@ bool CookieMonster::SetCanonicalCookies(const CookieList& list) { |
void CookieMonster::InternalUpdateCookieAccessTime(CanonicalCookie* cc, |
const Time& current) { |
- lock_.AssertAcquired(); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
// Based off the Mozilla code. When a cookie has been accessed recently, |
// don't bother updating its access time again. This reduces the number of |
@@ -1852,7 +1815,7 @@ void CookieMonster::InternalUpdateCookieAccessTime(CanonicalCookie* cc, |
void CookieMonster::InternalDeleteCookie(CookieMap::iterator it, |
bool sync_to_store, |
DeletionCause deletion_cause) { |
- lock_.AssertAcquired(); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
// Ideally, this would be asserted up where we define ChangeCauseMapping, |
// but DeletionCause's visibility (or lack thereof) forces us to make |
@@ -1878,7 +1841,7 @@ void CookieMonster::InternalDeleteCookie(CookieMap::iterator it, |
if (mapping.notify) |
delegate_->OnCookieChanged(*cc, true, mapping.cause); |
} |
- RunCallbacks(*cc, true); |
+ RunCookieChangedCallbacks(*cc, true); |
cookies_.erase(it); |
delete cc; |
} |
@@ -1888,7 +1851,7 @@ void CookieMonster::InternalDeleteCookie(CookieMap::iterator it, |
size_t CookieMonster::GarbageCollect(const Time& current, |
const std::string& key, |
bool enforce_strict_secure) { |
- lock_.AssertAcquired(); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
size_t num_deleted = 0; |
Time safe_date(Time::Now() - TimeDelta::FromDays(kSafeFromGlobalPurgeDays)); |
@@ -2118,7 +2081,7 @@ size_t CookieMonster::GarbageCollectNumFromRangeWithQuota( |
size_t CookieMonster::GarbageCollectExpired(const Time& current, |
const CookieMapItPair& itpair, |
CookieItVector* cookie_its) { |
- lock_.AssertAcquired(); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
int num_deleted = 0; |
for (CookieMap::iterator it = itpair.first, end = itpair.second; it != end;) { |
@@ -2139,7 +2102,7 @@ size_t CookieMonster::GarbageCollectExpired(const Time& current, |
size_t CookieMonster::GarbageCollectNonSecure( |
const CookieItVector& valid_cookies, |
CookieItVector* cookie_its) { |
- lock_.AssertAcquired(); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
size_t num_deleted = 0; |
for (const auto& curr_cookie_it : valid_cookies) { |
@@ -2159,6 +2122,8 @@ size_t CookieMonster::GarbageCollectDeleteRange( |
DeletionCause cause, |
CookieItVector::iterator it_begin, |
CookieItVector::iterator it_end) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
for (CookieItVector::iterator it = it_begin; it != it_end; it++) { |
histogram_evicted_last_access_minutes_->Add( |
(current - (*it)->second->LastAccessDate()).InMinutes()); |
@@ -2172,6 +2137,8 @@ size_t CookieMonster::GarbageCollectLeastRecentlyAccessed( |
const base::Time& safe_date, |
size_t purge_goal, |
CookieItVector cookie_its) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
// Sorts up to *and including* |cookie_its[purge_goal]|, so |
// |earliest_access_time| will be properly assigned even if |
// |global_purge_it| == |cookie_its.begin() + purge_goal|. |
@@ -2213,6 +2180,8 @@ size_t CookieMonster::GarbageCollectLeastRecentlyAccessed( |
// be worth it, but is still too much trouble to solve what is currently a |
// non-problem). |
std::string CookieMonster::GetKey(const std::string& domain) const { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
std::string effective_domain( |
registry_controlled_domains::GetDomainAndRegistry( |
domain, registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)); |
@@ -2225,7 +2194,7 @@ std::string CookieMonster::GetKey(const std::string& domain) const { |
} |
bool CookieMonster::HasCookieableScheme(const GURL& url) { |
- lock_.AssertAcquired(); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
// Make sure the request is on a cookie-able url scheme. |
for (size_t i = 0; i < cookieable_schemes_.size(); ++i) { |
@@ -2251,6 +2220,8 @@ bool CookieMonster::HasCookieableScheme(const GURL& url) { |
// in the constructor so that we won't take statistics right after |
// startup, to avoid bias from browsers that are started but not used. |
void CookieMonster::RecordPeriodicStats(const base::Time& current_time) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
const base::TimeDelta kRecordStatisticsIntervalTime( |
base::TimeDelta::FromSeconds(kRecordStatisticsIntervalSeconds)); |
@@ -2291,6 +2262,8 @@ void CookieMonster::RecordPeriodicStats(const base::Time& current_time) { |
// methods where needed. The specific histogram macro calls on which the |
// initialization is based are included in comments below. |
void CookieMonster::InitializeHistograms() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
// From UMA_HISTOGRAM_CUSTOM_COUNTS |
histogram_expiration_duration_minutes_ = base::Histogram::FactoryGet( |
"Cookie.ExpirationDurationMinutes", 1, kMinutesInTenYears, 50, |
@@ -2334,14 +2307,14 @@ Time CookieMonster::CurrentTime() { |
void CookieMonster::DoCookieTask( |
const scoped_refptr<CookieMonsterTask>& task_item) { |
- { |
- base::AutoLock autolock(lock_); |
- MarkCookieStoreAsInitialized(); |
- FetchAllCookiesIfNecessary(); |
- if (!finished_fetching_all_cookies_ && store_.get()) { |
- tasks_pending_.push(task_item); |
- return; |
- } |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
+ MarkCookieStoreAsInitialized(); |
+ FetchAllCookiesIfNecessary(); |
+ |
+ if (!finished_fetching_all_cookies_ && store_.get()) { |
+ tasks_pending_.push(task_item); |
+ return; |
} |
task_item->Run(); |
@@ -2350,34 +2323,35 @@ void CookieMonster::DoCookieTask( |
void CookieMonster::DoCookieTaskForURL( |
const scoped_refptr<CookieMonsterTask>& task_item, |
const GURL& url) { |
- { |
- base::AutoLock autolock(lock_); |
- MarkCookieStoreAsInitialized(); |
- if (ShouldFetchAllCookiesWhenFetchingAnyCookie()) |
- FetchAllCookiesIfNecessary(); |
- // If cookies for the requested domain key (eTLD+1) have been loaded from DB |
- // then run the task, otherwise load from DB. |
- if (!finished_fetching_all_cookies_ && store_.get()) { |
- // Checks if the domain key has been loaded. |
- std::string key( |
- cookie_util::GetEffectiveDomain(url.scheme(), url.host())); |
- if (keys_loaded_.find(key) == keys_loaded_.end()) { |
- std::map<std::string, |
- std::deque<scoped_refptr<CookieMonsterTask>>>::iterator it = |
- tasks_pending_for_key_.find(key); |
- if (it == tasks_pending_for_key_.end()) { |
- store_->LoadCookiesForKey( |
- key, base::Bind(&CookieMonster::OnKeyLoaded, this, key)); |
- it = tasks_pending_for_key_ |
- .insert(std::make_pair( |
- key, std::deque<scoped_refptr<CookieMonsterTask>>())) |
- .first; |
- } |
- it->second.push_back(task_item); |
- return; |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
+ MarkCookieStoreAsInitialized(); |
+ if (ShouldFetchAllCookiesWhenFetchingAnyCookie()) |
+ FetchAllCookiesIfNecessary(); |
+ |
+ // If cookies for the requested domain key (eTLD+1) have been loaded from DB |
+ // then run the task, otherwise load from DB. |
+ if (!finished_fetching_all_cookies_ && store_.get()) { |
+ // Checks if the domain key has been loaded. |
+ std::string key(cookie_util::GetEffectiveDomain(url.scheme(), url.host())); |
+ if (keys_loaded_.find(key) == keys_loaded_.end()) { |
+ std::map<std::string, |
+ std::deque<scoped_refptr<CookieMonsterTask>>>::iterator it = |
+ tasks_pending_for_key_.find(key); |
+ if (it == tasks_pending_for_key_.end()) { |
+ store_->LoadCookiesForKey( |
+ key, base::Bind(&CookieMonster::OnKeyLoaded, |
+ weak_ptr_factory_.GetWeakPtr(), key)); |
+ it = tasks_pending_for_key_ |
+ .insert(std::make_pair( |
+ key, std::deque<scoped_refptr<CookieMonsterTask>>())) |
+ .first; |
} |
+ it->second.push_back(task_item); |
+ return; |
} |
} |
+ |
task_item->Run(); |
} |
@@ -2385,6 +2359,8 @@ void CookieMonster::ComputeCookieDiff(CookieList* old_cookies, |
CookieList* new_cookies, |
CookieList* cookies_to_add, |
CookieList* cookies_to_delete) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
DCHECK(old_cookies); |
DCHECK(new_cookies); |
DCHECK(cookies_to_add); |
@@ -2414,16 +2390,22 @@ void CookieMonster::ComputeCookieDiff(CookieList* old_cookies, |
FullDiffCookieSorter); |
} |
-void CookieMonster::RunCallbacks(const CanonicalCookie& cookie, bool removed) { |
- lock_.AssertAcquired(); |
+void CookieMonster::RunCallback(const base::Closure& callback) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ callback.Run(); |
+} |
+ |
+void CookieMonster::RunCookieChangedCallbacks(const CanonicalCookie& cookie, |
+ bool removed) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
CookieOptions opts; |
opts.set_include_httponly(); |
opts.set_include_same_site(); |
- // Note that the callbacks in hook_map_ are wrapped with MakeAsync(), so they |
+ // Note that the callbacks in hook_map_ are wrapped with RunAsync(), so they |
// are guaranteed to not take long - they just post a RunAsync task back to |
- // the appropriate thread's message loop and return. It is important that this |
- // method not run user-supplied callbacks directly, since the CookieMonster |
- // lock is held and it is easy to accidentally introduce deadlocks. |
+ // the appropriate thread's message loop and return. |
+ // TODO(mmenke): Consider running these synchronously? |
for (CookieChangedHookMap::iterator it = hook_map_.begin(); |
it != hook_map_.end(); ++it) { |
std::pair<GURL, std::string> key = it->first; |