summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/api/api_resource_manager.h
diff options
context:
space:
mode:
authorrpaquay@chromium.org <rpaquay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-16 02:05:26 +0000
committerrpaquay@chromium.org <rpaquay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-16 02:05:26 +0000
commit64a3996dc779333627f34e4e46be2a23b9539551 (patch)
tree8e1e0829056207efdea2c70258f33d2d92bc0e2e /chrome/browser/extensions/api/api_resource_manager.h
parent6a078da35f5fcf238013a837ab33e4a16e00d0a8 (diff)
downloadchromium_src-64a3996dc779333627f34e4e46be2a23b9539551.zip
chromium_src-64a3996dc779333627f34e4e46be2a23b9539551.tar.gz
chromium_src-64a3996dc779333627f34e4e46be2a23b9539551.tar.bz2
Implement v2 API of udp socket.
(Note this issue is a replacement for issue #19260002 that will not accept additional patch sets due to a corruption bug: https://code.google.com/p/chromium/issues/detail?id=107101). One notable change vs socket v1 is the use of event handlers for receiving data instead of using callbacks with the "recvFrom" function. This allow server apps to go to "suspend" mode when inactive (see https://docs.google.com/document/d/1qGytoYz6K0xYnOR6oM2tpxC0ET8bbb8XdTFMq4K9jTU/edit?usp=sharing), as well as improve performance (#packets/sec) (see https://docs.google.com/spreadsheet/ccc?key=0Ar6WDZ-sS7b5dEp1ckJGQjZEVGlFN3A1U1BVQUdQb2c&usp=sharing). Also implement the "close_on_suspend" behavior wrt to lifetime: By default, sockets are closed when the packaged app process dies (unload or suspend). When "close_on_suspend" is 'false', sockets survive "suspend" events, and thus can be re-used across process re-activation. This is useful for background server type apps. BUG=165273 BUG=173241 Review URL: https://chromiumcodereview.appspot.com/22650003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@217912 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions/api/api_resource_manager.h')
-rw-r--r--chrome/browser/extensions/api/api_resource_manager.h87
1 files changed, 78 insertions, 9 deletions
diff --git a/chrome/browser/extensions/api/api_resource_manager.h b/chrome/browser/extensions/api/api_resource_manager.h
index d357ebe..a7c1624 100644
--- a/chrome/browser/extensions/api/api_resource_manager.h
+++ b/chrome/browser/extensions/api/api_resource_manager.h
@@ -7,11 +7,13 @@
#include <map>
+#include "base/containers/hash_tables.h"
#include "base/lazy_instance.h"
#include "base/memory/linked_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/api/profile_keyed_api_factory.h"
+#include "chrome/browser/extensions/extension_host.h"
#include "chrome/common/extensions/extension.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
#include "content/public/browser/browser_thread.h"
@@ -69,6 +71,10 @@ class ApiResourceManager : public ProfileKeyedAPI,
this,
chrome::NOTIFICATION_EXTENSION_UNLOADED,
content::NotificationService::AllSources());
+ registrar_.Add(
+ this,
+ chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED,
+ content::NotificationService::AllSources());
}
// For Testing.
@@ -113,6 +119,10 @@ class ApiResourceManager : public ProfileKeyedAPI,
return data_->Get(extension_id, api_resource_id);
}
+ base::hash_set<int>* GetResourceIds(const std::string& extension_id) {
+ return data_->GetResourceIds(extension_id);
+ }
+
protected:
// content::NotificationObserver:
virtual void Observe(int type,
@@ -123,7 +133,12 @@ class ApiResourceManager : public ProfileKeyedAPI,
std::string id =
content::Details<extensions::UnloadedExtensionInfo>(details)->
extension->id();
- data_->InitiateCleanup(id);
+ data_->InitiateExtensionUnloadedCleanup(id);
+ break;
+ }
+ case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: {
+ ExtensionHost* host = content::Details<ExtensionHost>(details).ptr();
+ data_->InitiateExtensionSuspendedCleanup(host->extension_id());
break;
}
}
@@ -185,9 +200,20 @@ class ApiResourceManager : public ProfileKeyedAPI,
return GetOwnedResource(extension_id, api_resource_id);
}
- void InitiateCleanup(const std::string& extension_id) {
+ base::hash_set<int>* GetResourceIds(const std::string& extension_id) {
+ DCHECK(content::BrowserThread::CurrentlyOn(thread_id_));
+ return GetOwnedResourceIds(extension_id);
+ }
+
+ void InitiateExtensionUnloadedCleanup(const std::string& extension_id) {
+ content::BrowserThread::PostTask(thread_id_, FROM_HERE,
+ base::Bind(&ApiResourceData::CleanupResourcesFromUnloadedExtension,
+ base::Unretained(this), extension_id));
+ }
+
+ void InitiateExtensionSuspendedCleanup(const std::string& extension_id) {
content::BrowserThread::PostTask(thread_id_, FROM_HERE,
- base::Bind(&ApiResourceData::CleanupResourcesFromExtension,
+ base::Bind(&ApiResourceData::CleanupResourcesFromSuspendedExtension,
base::Unretained(this), extension_id));
}
@@ -201,16 +227,59 @@ class ApiResourceManager : public ProfileKeyedAPI,
return NULL;
}
- void CleanupResourcesFromExtension(const std::string& extension_id) {
+ base::hash_set<int>* GetOwnedResourceIds(const std::string& extension_id) {
DCHECK(content::BrowserThread::CurrentlyOn(thread_id_));
- if (extension_resource_map_.find(extension_id) !=
+ if (extension_resource_map_.find(extension_id) ==
+ extension_resource_map_.end())
+ return NULL;
+
+ return &extension_resource_map_[extension_id];
+ }
+
+ void CleanupResourcesFromUnloadedExtension(
+ const std::string& extension_id) {
+ CleanupResourcesFromExtension(extension_id, true);
+ }
+
+ void CleanupResourcesFromSuspendedExtension(
+ const std::string& extension_id) {
+ CleanupResourcesFromExtension(extension_id, false);
+ }
+
+ void CleanupResourcesFromExtension(const std::string& extension_id,
+ bool remove_all) {
+ DCHECK(content::BrowserThread::CurrentlyOn(thread_id_));
+
+ if (extension_resource_map_.find(extension_id) ==
extension_resource_map_.end()) {
- base::hash_set<int>& resource_ids =
- extension_resource_map_[extension_id];
- for (base::hash_set<int>::iterator it = resource_ids.begin();
- it != resource_ids.end(); ++it) {
+ return;
+ }
+
+ // Remove all resources, or the non persistent ones only if |remove_all|
+ // is false.
+ base::hash_set<int>& resource_ids =
+ extension_resource_map_[extension_id];
+ for (base::hash_set<int>::iterator it = resource_ids.begin();
+ it != resource_ids.end(); ) {
+ bool erase = false;
+ if (remove_all) {
+ erase = true;
+ } else {
+ linked_ptr<T> ptr = api_resource_map_[*it];
+ T* resource = ptr.get();
+ erase = (resource && !resource->persistent());
+ }
+
+ if (erase) {
api_resource_map_.erase(*it);
+ resource_ids.erase(it++);
+ } else {
+ ++it;
}
+ } // end for
+
+ // Remove extension entry if we removed all its resources.
+ if (resource_ids.size() == 0) {
extension_resource_map_.erase(extension_id);
}
}