STACK_WIND_COOKIE
在ec_open函數中,調用了STACK_WIND_COOKIE函數
作用:
1、爲ec xlator下層的vclnt xlator,新建一個frame
2、給vclnt frame賦值(包括wind_from = ec_open、wind_to = vclnt_open、unwind_to = ec_open_cbk)
其中unwind_to用於vclnt_open_cbk調用完,調用UNWIND向上返回,繼續調用ec_open_cbk
3、向下層xlator繼續下發open請求,即調用vclnt_open
STACK_WIND_COOKIE(frame, ec_open_cbk, (void *) (long) i,
priv->child_xl_list[i],
priv->child_xl_list[i]->fops->open,
loc, wind_flags, fd, dict);
/* make a call with a cookie */
/*
** frame ec的frame
** rfn cbk函數 = ec_open_cbk
** cky cookie
** obj 下次調用的xlator:priv->child_xl_list[i]
** fn 下次調用的xlator:priv->child_xl_list[i]->fops->open = vclnt_open
** params loc, wind_flags, fd, dict
**
** 總體思想:
** 1、新建 frame(_new),給它賦值
** 2、調用 vclnt_open(_new, obj, params);
*/
#define STACK_WIND_COOKIE(frame, rfn, cky, obj, fn, params ...) \
do { \
/* 創建新的frame */ \
call_frame_t *_new = NULL; \
xlator_t *old_THIS = NULL; \
\
/* 從內存池中獲取call_frame_t */ \
_new = call_frame_get (frame->root); \
if (!_new) { \
gf_log ("stack", GF_LOG_ERROR, "alloc failed"); \
break; \
} \
/* _new的初始化 */ \
typeof(fn##_cbk) tmp_cbk = rfn; \
/* frame的root都是相同的 */ \
_new->root = frame->root; \
/* 新的xlator的this指針指向obj,合情合理!*/ \
_new->this = obj; \
/* [特殊]ret竟然存放的是cbk函數rfn */ \
_new->ret = (ret_fn_t) tmp_cbk; \
/* _new的parent是當前的frame */ \
_new->parent = frame; \
_new->flag |= frame->flag; \
/* cookie的作用?當UNWIND時,取出來用 */ \
_new->cookie = cky; \
\
/* ec_open */ \
_new->wind_from = __FUNCTION__; \
/* vclnt_open */ \
_new->wind_to = #fn; \
/* ec_open_cbk */ \
_new->unwind_to = #rfn; \
/* local_bak[?]:什麼用? */ \
frame->local_bak = frame->local; \
LOCK_INIT (&_new->lock); \
LOCK(&frame->root->stack_lock); \
{ \
/* ec的frame引用計數加一 */ \
frame->ref_count++; \
_new->next = frame->root->frames.next; \
_new->prev = &frame->root->frames; \
if (frame->root->frames.next) \
frame->root->frames.next->prev = _new; \
frame->root->frames.next = _new; \
} \
UNLOCK(&frame->root->stack_lock); \
\
/* vclnt_open_cbk = ec