Squid Web Cache Wiki

Squid Web Cache 文档

🔗 引用计数数据分配器 (仅限 C++)

像 cbdata 使用的手动引用计数很容易出错,并且对程序员来说很耗时。C++ 的运算符重载允许我们创建自动引用计数指针,这些指针将在不再需要对象时释放它们。通过一些谨慎的操作,这些对象可以传递给需要回调数据指针的函数。

🔗 API

自动引用计数涉及两个类 - 一个 RefCountable 类,它为给定派生类的引用计数提供机制。以及一个 ‘RefCount’ 类,它是智能指针,处理 const 正确性,并通知 RefCountable 类引用和取消引用的情况。

🔗 RefCountable

RefCountable 基类定义了一个抽象函数 - deleteSelf()。您必须为每个具体类实现 deleteSelf。deleteSelf() 是对‘operator delete’不是虚函数的一种变通方法。delete Self 通常如下所示:

void deleteSelf() const {delete this;}

🔗 RefCount

RefCount 模板类替换了被引用计数类的参数和变量的指针。通常,人们会创建一个 typedef 来方便用户。

class MyConcrete : public RefCountable {
  public:
    typedef RefCount<MyConcrete> Pointer;
    void deleteSelf() const {delete this;}
};

现在,可以传递 MyConcrete::Pointer 的对象了。

🔗 CBDATA

要创建一个引用计数的 CBDATA 类,您需要重载 new 和 delete,在您的类定义中包含一个宏,并确保任何直接调用您的人(不是作为 cbdata 回调,而是作为正常使用)都持有您对象的 RefCount<> 智能指针。

 class MyConcrete : public RefCountable {
   public:
     typedef RefCount<MyConcrete> Pointer;
     void * operator new(size_t);
     void operator delete (void *);
     void deleteSelf() const {delete this;}
   private:
     CBDATA_CLASS(MyConcrete);
 };

 ...
 /* In your .cc file */
 CBDATA_CLASS_INIT(MyConcrete);

 void *
 MyConcrete::operator new (size_t)
 {
   CBDATA_INIT_TYPE(MyConcrete);
   MyConcrete *result = cbdataAlloc(MyConcrete);
   /* Mark result as being owned - we want the refcounter to do the
    * delete call
    */
   cbdataReference(result);
   return result;
 }

 void
 MyConcrete::operator delete (void *address)
 {
   MyConcrete *t = static_cast<MyConcrete *>(address);
   cbdataFree(address);
   /* And allow the memory to be freed */
   cbdataReferenceDone (t);
 }

当不存在 RefCount<MyConcrete> 智能指针时,将调用对象的 delete 方法。这将运行对象析构函数,释放它持有的任何外部资源。然后将调用 cbdataFree,将对象标记为对它可能已排队的任何 cbdata 函数无效。当所有这些都返回后,实际的内存将被返还给池。

🔗 使用引用计数器

引用计数对象的分配和释放(包括 RefCount 模板类的对象)必须通过 new() 和 delete() 来完成。如果一个将持有 RefCount <foo> 变量实例的类不使用 delete(),则在释放该变量之前,您必须将其赋值为 NULL。否则将导致内存泄漏。您已被警告。

切勿在 RefCountable 对象上调用 delete 或 deleteSelf。您将创建大量悬空引用,并且 Squid 最终会发生段错误。

始终创建至少一个 RefCount 智能指针,以便在对象不再需要时,引用计数机制会删除它。

不要将 RefCount 智能指针传递到 Squid 内存空间之外。它们在复制时不可避免地会发生段错误。

如果在某个方法中,所有其他持有智能指针的对象都可能被删除或将其智能指针设置为 NULL,那么您将在方法执行过程中被删除(从而崩溃)。为防止这种情况,请将一个智能指针赋值给自己。

    void
    MyConcrete::aMethod(){
      /* This holds a reference to us */
      Pointer aPointer(this);
      /* This is a method that may mean we don't need to exist anymore */
      someObject->someMethod();
      /* This prevents aPointer being optimised away before this point,
       * and must be the last line in our method
       */
      aPointer = NULL;
    }

通过智能指针调用方法很容易,只需使用 -> 进行解引用即可。

    void
    SomeObject::someFunction() {
      myConcretePointer->someOtherMethod();
    }

传递 RefCount 智能指针时,始终将它们作为其原生类型传递,切勿作为 ‘*’ 或 ‘&’ 传递。

导航:网站搜索网站页面分类🔼 向上