squid回调参数的生命周期是用cbdata方式管理的,cbdata就是一个memory pool manager,用这些memory pool生成回调参数对象,其生命周期是用其中的int locks;标示管理的,其cbdata定义如下:
typedef struct _cbdata {
#if HASHED_CBDATA
hash_link hash;
#endif
int valid;
int locks;
int type;
#if CBDATA_DEBUG
const char *file;
int line;
#endif
void *y; /* cookie used while debugging */
#if !HASHED_CBDATA
union {
void *pointer;
double double_float;
int integer;
} data;
#endif
} cbdata;
如上cbdata结构,其中data才是我们真正回调参数对象指针,是一个union结构,可以可以表示任意的对象,locks就是object reference count,当locks==0的时候就是生命周期结束的时候了!y不是很清楚她为什么用cookie来表示,看代码其实就是dada变量做的一次位运算,并在使用中做校验的作用!!!
#define CBDATA_COOKIE(p) ((void *)((unsigned long)(p) ^ 0xDEADBEEF))
如上的宏就是cbdata中字段y的取值,参数就是cbdata中data字段,其中0xDEADBEEF很奇怪,查了Wikipedia,说一个Magic number,它们的作用应该就是为内存做标记,插在那里,就表示从这个位置往后的一段有特殊作用的内存,而这个位置往前,禁止访问,看y在cbdata的位置有这个味道。如下是Wikipedia的解释:
DEADBEEF | Famously used on IBM systems such as the RS/6000, also used in the original Mac OS operating systems, OPENSTEP Enterprise, and the Commodore Amiga. On Sun Microsystems' Solaris, marks freed kernel memory (KMEM_FREE_PATTERN) |
squid定义了很多预定义的memory pool type 【cbdata_type】,如下:
typedef enum {
CBDATA_UNKNOWN = 0,
CBDATA_UNDEF = 0,
CBDATA_acl_access,
CBDATA_aclCheck_t,
CBDATA_clientHttpRequest,
CBDATA_ConnStateData,
CBDATA_ErrorState,
CBDATA_FwdState,
CBDATA_generic_cbdata,
CBDATA_helper,
CBDATA_helper_server,
CBDATA_statefulhelper,
CBDATA_helper_stateful_server,
CBDATA_HttpStateData,
CBDATA_peer,
CBDATA_ps_state,
CBDATA_RemovalPolicy,
CBDATA_RemovalPolicyWalker,
CBDATA_RemovalPurgeWalker,
CBDATA_store_client,
CBDATA_FIRST_CUSTOM_TYPE = 1000
} cbdata_type;
如上可以看出都加了一个CBDATA_的头,剩下的部分,如acl_access,就是对应其结构对象acl_access,对预先定义好了的cbdata_type用cbdataInit()进行创建memory pool。每种类型对应一种memory pool type,memory pool 结构如下:
struct {
MemPool *pool;
FREE *free_func;
} *cbdata_index = NULL;
cbdata中添加新对象的分成2步做,先添加cbdata_type,然后添加cbdata_index,总的来说这个是构建在squid的基础memory pool结构MemPool之上,独立出回调参数独有的特性。
大家都知道上面的cbdata_type是不够用的,当我们想往其中添加新的回调对象的时候该怎么弄的呢?需要直接在cbdata_type中添加枚举,并在cbdataInit中添加相应的初始化?其实没有这样麻烦。squid中有额外添加cbdata_type的方法,只要代码中grep一下CBDATA_INIT_TYPE,满山遍野都是这个东东的调用,这个宏的作用就是添加cbdata_type,简单说下代码code step:
CBDATA_INIT_TYPE(RebuildState);
rb = cbdataAlloc(RebuildState);
CBDATA_INIT_TYPE_FREECB(storeIOState, storeAufsIOFreeEntry);
sio = cbdataAlloc(storeIOState);
如上只是2中用法而已,其中的道理你是懂得!
。。。。
。。。。
代码就不分析了,分析代码要被人鄙视的,,,,太俗气了!!