• 从微观看chrome 之二:围绕Profile的ProfileService系统


    本来要上下简单的uml图,但是不知道怎么穿不上来,就简单描述下巴。

    Chrome中profile是一个核心的对象,profile用来进行chrome账户之间的隔离,不用的账户所持有的profile不一样。所有的逻辑或多或少,直接间接的都与他发生关联。大部分的chrome服务类, 都可以通过profile来获取。这些服务类彼此之间相互依赖,提供基础的服务给浏览器的上层使用,本文大概分析下这些服务的实现结构。

    实现上来说每个service都有对应的一个继承自ProfileKeyedServiceFactory的一个对应工厂类。工厂类以Singleton<>类为实体存在,维护了每个profile所对应的service的生命周期。ProfileKeyedServiceFactory负责生产service的实体对象,用map保存profile和service之间的对应关系.同时借助于ProfileDependencyManager来维护各个Service之间的互相依赖关系。摘抄一个Service的核心代码如下:

    class ExtensionActionManager : public ProfileKeyedService,
                                   public content::NotificationObserver {
     public:
      ..........
     
    static ExtensionActionManager* Get(Profile* profile)
    {
       return ExtensionActionManagerFactory::GetForProfile(profile);
    }
    .......................
    };
    class ExtensionActionManagerFactory : public ProfileKeyedServiceFactory {
     public:
      // ProfileKeyedServiceFactory implementation:
      static ExtensionActionManager* GetForProfile(Profile* profile) {
        return static_cast<ExtensionActionManager*>(
            GetInstance()->GetServiceForProfile(profile, true));
      }
    
      static ExtensionActionManagerFactory* GetInstance();
    
     private:
      friend struct DefaultSingletonTraits<ExtensionActionManagerFactory>;
    
      ExtensionActionManagerFactory()
          : ProfileKeyedServiceFactory("ExtensionActionManager",
                                       ProfileDependencyManager::GetInstance()) {
      }
    
      virtual ProfileKeyedService* BuildServiceInstanceFor(
          Profile* profile) const OVERRIDE {
        return new ExtensionActionManager(profile);
      }
    
      virtual bool ServiceRedirectedInIncognito() const OVERRIDE {
        return true;
      }
    };
    
    ExtensionActionManagerFactory*
    ExtensionActionManagerFactory::GetInstance() {
      return Singleton<ExtensionActionManagerFactory>::get();
    }

    通过ExtensionActionManager::Get函数可以获取到某个profile对应的service,通过上面的代码可以清晰地看到ExtensionActionManagerFactory和ExtensionActionManager之间的关系,要全读懂的话,最好看下ProfileKeyedServiceFactory 的源码。

    chrome中的service实现相对来说简单,但是管理service之间依赖关系的ProfileDependencyManager值得研究下. 该类内部已有向图的方式管理各个service, 程序运行时建立起各个服务组件间的依赖关系, 然后通过 有向图排列出 服务的创建和销毁顺序. 把用算法排序的函数超出来看看

    void ProfileDependencyManager::BuildDestructionOrder(Profile* profile) {
    
      // Step 1: Build a set of nodes with no incoming edges.
      std::deque<ProfileKeyedBaseFactory*> queue;
      std::copy(all_components_.begin(),
                all_components_.end(),
                std::back_inserter(queue));
    
      std::deque<ProfileKeyedBaseFactory*>::iterator queue_end = queue.end();
      for (EdgeMap::const_iterator it = edges_.begin();
           it != edges_.end(); ++it) {
        queue_end = std::remove(queue.begin(), queue_end, it->second);
      }
      queue.erase(queue_end, queue.end());
    
      // Step 2: Do the Kahn topological sort.
      std::vector<ProfileKeyedBaseFactory*> output;
      EdgeMap edges(edges_);
      while (!queue.empty()) {
        ProfileKeyedBaseFactory* node = queue.front();
        queue.pop_front();
        output.push_back(node);
    
        std::pair<EdgeMap::iterator, EdgeMap::iterator> range =
            edges.equal_range(node);
        EdgeMap::iterator it = range.first;
        while (it != range.second) {
          ProfileKeyedBaseFactory* dest = it->second;
          EdgeMap::iterator temp = it;
          it++;
          edges.erase(temp);
    
          bool has_incoming_edges = false;
          for (EdgeMap::iterator jt = edges.begin(); jt != edges.end(); ++jt) {
            if (jt->second == dest) {
              has_incoming_edges = true;
              break;
            }
          }
    
          if (!has_incoming_edges)
            queue.push_back(dest);
        }
      }
    
      if (edges.size()) {
        NOTREACHED() << "Dependency graph has a cycle. We are doomed.";
      }
    
      std::reverse(output.begin(), output.end());
      destruction_order_ = output;
    }
  • 相关阅读:
    POJMatrix(二维树状数组)
    HD1556Color the ball(树状数组)
    闲的没事,自挂东南枝
    高端、洋气效果
    “绝对”妹纸~position
    float元素一定要闭合
    dw cs6激活码一枚
    shell 预定义变量
    ubuntu 安装docker
    Microsonf visual c++ 14+ 离线内网安装
  • 原文地址:https://www.cnblogs.com/kwliu/p/3116053.html
Copyright © 2020-2023  润新知