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

Unified Diff: chrome/browser/extensions/api/alarms/alarm_manager.h

Issue 22900005: Fixing race conditions in chrome.alarms (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 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
« no previous file with comments | « no previous file | chrome/browser/extensions/api/alarms/alarm_manager.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/extensions/api/alarms/alarm_manager.h
diff --git a/chrome/browser/extensions/api/alarms/alarm_manager.h b/chrome/browser/extensions/api/alarms/alarm_manager.h
index 66ebfc8408a9cadd429c77e832049989f7dced1c..3f92db8dcef53cd1e293a87a9030ad62dcf5ae98 100644
--- a/chrome/browser/extensions/api/alarms/alarm_manager.h
+++ b/chrome/browser/extensions/api/alarms/alarm_manager.h
@@ -6,9 +6,11 @@
#define CHROME_BROWSER_EXTENSIONS_API_ALARMS_ALARM_MANAGER_H__
#include <map>
+#include <queue>
#include <string>
#include <vector>
+#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "chrome/browser/extensions/api/profile_keyed_api_factory.h"
@@ -67,24 +69,38 @@ class AlarmManager
// Override the default delegate. Callee assumes onwership. Used for testing.
void set_delegate(Delegate* delegate) { delegate_.reset(delegate); }
- // Adds |alarm| for the given extension, and starts the timer.
+ typedef base::Callback<void()> AddAlarmCallback;
+ // Adds |alarm| for the given extension, and starts the timer. Invokes
+ // |callback| when done.
void AddAlarm(const std::string& extension_id,
- const Alarm& alarm);
-
- // Returns the alarm with the given name, or NULL if none exists.
- const Alarm* GetAlarm(const std::string& extension_id,
- const std::string& name);
-
- // Returns the list of pending alarms for the given extension, or NULL
- // if none exist.
- const AlarmList* GetAllAlarms(const std::string& extension_id);
-
- // Cancels and removes the alarm with the given name.
- bool RemoveAlarm(const std::string& extension_id,
- const std::string& name);
-
- // Cancels and removes all alarms for the given extension.
- void RemoveAllAlarms(const std::string& extension_id);
+ const Alarm& alarm,
+ const AddAlarmCallback& callback);
+
+ typedef base::Callback<void(Alarm*)> GetAlarmCallback;
+ // Passes the alarm with the given name, or NULL if none exists, to
+ // |callback|.
+ void GetAlarm(const std::string& extension_id,
+ const std::string& name,
+ const GetAlarmCallback& callback);
+
+ typedef base::Callback<void(const AlarmList*)> GetAllAlarmsCallback;
+ // Passes the list of pending alarms for the given extension, or
+ // NULL if none exist, to |callback|.
+ void GetAllAlarms(
+ const std::string& extension_id, const GetAllAlarmsCallback& callback);
+
+ typedef base::Callback<void(bool)> RemoveAlarmCallback;
+ // Cancels and removes the alarm with the given name. Invokes |callback| when
+ // done.
+ void RemoveAlarm(const std::string& extension_id,
+ const std::string& name,
+ const RemoveAlarmCallback& callback);
+
+ typedef base::Callback<void()> RemoveAllAlarmsCallback;
+ // Cancels and removes all alarms for the given extension. Invokes |callback|
+ // when done.
+ void RemoveAllAlarms(
+ const std::string& extension_id, const RemoveAllAlarmsCallback& callback);
// Replaces AlarmManager's owned clock with |clock| and takes ownership of it.
void SetClockForTesting(base::Clock* clock);
@@ -96,8 +112,7 @@ class AlarmManager
static AlarmManager* Get(Profile* profile);
private:
- FRIEND_TEST_ALL_PREFIXES(ExtensionAlarmsTest, CreateRepeating);
- FRIEND_TEST_ALL_PREFIXES(ExtensionAlarmsTest, Clear);
+ friend void RunScheduleNextPoll(AlarmManager*);
friend class ExtensionAlarmsSchedulingTest;
FRIEND_TEST_ALL_PREFIXES(ExtensionAlarmsSchedulingTest, PollScheduling);
FRIEND_TEST_ALL_PREFIXES(ExtensionAlarmsSchedulingTest,
@@ -108,10 +123,37 @@ class AlarmManager
typedef std::string ExtensionId;
typedef std::map<ExtensionId, AlarmList> AlarmMap;
+ typedef base::Callback<void(const std::string&)> ReadyAction;
+ typedef std::queue<ReadyAction> ReadyQueue;
+ typedef std::map<ExtensionId, ReadyQueue> ReadyMap;
+
// Iterator used to identify a particular alarm within the Map/List pair.
// "Not found" is represented by <alarms_.end(), invalid_iterator>.
typedef std::pair<AlarmMap::iterator, AlarmList::iterator> AlarmIterator;
+ // Part of AddAlarm that is executed after alarms are loaded.
+ void AddAlarmWhenReady(const Alarm& alarm,
+ const AddAlarmCallback& callback,
+ const std::string& extension_id);
+
+ // Part of GetAlarm that is executed after alarms are loaded.
+ void GetAlarmWhenReady(const std::string& name,
+ const GetAlarmCallback& callback,
+ const std::string& extension_id);
+
+ // Part of GetAllAlarms that is executed after alarms are loaded.
+ void GetAllAlarmsWhenReady(const GetAllAlarmsCallback& callback,
+ const std::string& extension_id);
+
+ // Part of RemoveAlarm that is executed after alarms are loaded.
+ void RemoveAlarmWhenReady(const std::string& name,
+ const RemoveAlarmCallback& callback,
+ const std::string& extension_id);
+
+ // Part of RemoveAllAlarms that is executed after alarms are loaded.
+ void RemoveAllAlarmsWhenReady(
+ const RemoveAllAlarmsCallback& callback, const std::string& extension_id);
+
// Helper to return the iterators within the AlarmMap and AlarmList for the
// matching alarm, or an iterator to the end of the AlarmMap if none were
// found.
@@ -142,6 +184,10 @@ class AlarmManager
// rescheduling repeating alarms, schedule the next poll.
void PollAlarms();
+ // Executes |action| for given extension, making sure that the extension's
+ // alarm data has been synced from the storage.
+ void RunWhenReady(const std::string& extension_id, const ReadyAction& action);
+
// NotificationObserver:
virtual void Observe(int type,
const content::NotificationSource& source,
@@ -165,9 +211,15 @@ class AlarmManager
// Invariant: None of the AlarmLists are empty.
AlarmMap alarms_;
- // The previous and next time that alarms were and will be run.
+ // A map of actions waiting for alarm data to be synced from storage, per
+ // extension.
+ ReadyMap ready_actions_;
+
+ // The previous time that alarms were run.
base::Time last_poll_time_;
- base::Time next_poll_time_;
+
+ // Next poll's time. Used only by unit tests.
+ base::Time test_next_poll_time_;
DISALLOW_COPY_AND_ASSIGN(AlarmManager);
};
« no previous file with comments | « no previous file | chrome/browser/extensions/api/alarms/alarm_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698