📄 ccmlib_memapi.c
字号:
if ((uname = OC_EV_GET_NODE(mbr_track, lpc).node_uname)){ g_free(uname); } } g_free(mbr_track); } return;}static voidmem_callback_done(void *cookie){ cookie_unref(cookie); return;}static voidupdate_bornons(mbr_private_t *private, mbr_track_t *mbr){ uint i,j; for(i=0; i < OC_EV_GET_N_MEMBER(mbr); i++) { g_hash_table_insert(private->bornon, GINT_TO_POINTER(OC_EV_GET_NODEID(mbr,i)), GINT_TO_POINTER(OC_EV_GET_BORN(mbr,i)+1)); } j=OC_EV_GET_OUT_IDX(mbr); for(i=OC_EV_GET_OUT_IDX(mbr); i<j+OC_EV_GET_N_OUT(mbr); i++){ g_hash_table_insert(private->bornon, GINT_TO_POINTER(OC_EV_GET_NODEID(mbr,i)), GINT_TO_POINTER(0)); }}static gbooleanmembership_unchanged(mbr_private_t *private, mbr_track_t *mbr){ uint i; mbr_track_t *oldmbr = (mbr_track_t *) cookie_get_data(private->cookie); if(!oldmbr) { return FALSE; } if(OC_EV_GET_N_MEMBER(mbr) != OC_EV_GET_N_MEMBER(oldmbr)){ return FALSE; } for(i=0; i < OC_EV_GET_N_MEMBER(mbr); i++) { if((OC_EV_GET_NODEID(mbr,i) != OC_EV_GET_NODEID(oldmbr,i)) || OC_EV_GET_BORN(mbr,i) != OC_EV_GET_BORN(oldmbr,i)) { return FALSE; } } return TRUE;}static gboolean mem_handle_event(class_t *class){ struct IPC_MESSAGE *msg; mbr_private_t *private; struct IPC_CHANNEL *ch; mbr_track_t *mbr_track; int size; int type; oc_memb_event_t oc_type; void *cookie; int ret; gboolean quorum; if(!class_valid(class)){ return FALSE; } private = (mbr_private_t *)class->private; ch = private->channel; if(init_llmborn(private)){ return FALSE; } while(ch->ops->is_message_pending(ch)){ /* receive the message and call the callback*/ ret=ch->ops->recv(ch,&msg); if(ret == IPC_FAIL) { return TRUE; } if(ret!=IPC_OK){ /* FIXIT. setting it to CCM_EVICTED is not * correct. However the draft api says nothing * about this case. * Proposal: * Set something like CCM_LOST_SERVICE here * and return OC_EV_MS_LOST_SERVICE to the * client */ type = CCM_EVICTED; } else { type = ((ccm_meminfo_t *)msg->msg_body)->ev; } cookie= mbr_track = NULL; size=0; oc_type = OC_EV_MS_INVALID; switch(type) { case CCM_NEW_MEMBERSHIP :{ ccm_meminfo_t* cmi = (ccm_meminfo_t*)msg->msg_body; size = get_new_membership(private, cmi, msg->msg_len, &mbr_track); mbr_track->quorum = quorum = cmi->quorum; /* if no quorum, delete the bornon dates for lost * nodes, add bornon dates for the new nodes and * return * * however if special behaviour is being asked * for report the membership even when this node * has no quorum. */ if (!private->special && !quorum){ update_bornons(private, mbr_track); private->client_report = FALSE; mem_free_func(mbr_track); break; } private->client_report = TRUE; /* if quorum and old membership is same as the new * membership set type to OC_EV_MS_RESTORED , * pick the old membership and deliver it. * Do not construct a new membership */ if (membership_unchanged(private, mbr_track)){ mbr_track_t* old_mbr_track; old_mbr_track = (mbr_track_t *) cookie_get_data(private->cookie); if (mbr_track->quorum == old_mbr_track->quorum){ /* nothing has changed*/ return TRUE; }else if (mbr_track->quorum){ oc_type = OC_EV_MS_PRIMARY_RESTORED; }else{ oc_type = OC_EV_MS_INVALID; } } else { oc_type = quorum? OC_EV_MS_NEW_MEMBERSHIP: OC_EV_MS_INVALID; /* NOTE: OC_EV_MS_INVALID overloaded to * mean that the membership has no quorum. * This is returned only when special behaviour * is asked for. In normal behaviour case * (as per 0.2 version of the api), * OC_EV_MS_INVALID is never returned. * I agree this is a kludge!! */ if(!private->special) { assert(oc_type == OC_EV_MS_NEW_MEMBERSHIP); } } update_bornons(private, mbr_track); cookie_unref(private->cookie); cookie = cookie_construct(mem_callback_done, mem_free_func, mbr_track); private->cookie = cookie; size = OC_EV_GET_SIZE(mbr_track); break; } case CCM_EVICTED: oc_type = OC_EV_MS_EVICTED; private->client_report = TRUE; /* FALL THROUGH */ case CCM_INFLUX: if(type==CCM_INFLUX){ oc_type = OC_EV_MS_NOT_PRIMARY; } cookie = private->cookie; if(cookie) { mbr_track = (mbr_track_t *) cookie_get_data(cookie); size=mbr_track? OC_EV_GET_SIZE(mbr_track): 0; } else { /* if no cookie exists, create one. * This can happen if no membership * has been delivered. */ mbr_track=NULL; size=0; cookie = private->cookie = cookie_construct(mem_callback_done, NULL,NULL); } break; } if(private->callback && private->client_report && cookie){ cookie_ref(cookie); private->callback(oc_type, (uint *)cookie, size, mbr_track?&(mbr_track->m_mem):NULL); } if(ret==IPC_OK) { msg->msg_done(msg); } else { return FALSE; } if(type == CCM_EVICTED) { /* clean up the dynamic information in the * private structure */ reset_llm(private); reset_bornon(private); cookie_unref(private->cookie); private->cookie = NULL; } } return TRUE;}static int mem_activate(class_t *class){ mbr_private_t *private; struct IPC_CHANNEL *ch; int sockfd; if(!class_valid(class)) { return -1; } /* if already activated */ private = (mbr_private_t *)class->private; if(private->llm){ return -1; } ch = private->channel; if(!ch || ch->ops->initiate_connection(ch) != IPC_OK) { return -1; } sockfd = ch->ops->get_recv_select_fd(ch); return sockfd;}static voidmem_unregister(class_t *class){ mbr_private_t *private; struct IPC_CHANNEL *ch; private = (mbr_private_t *)class->private; ch = private->channel; /* TOBEDONE * call all instances, of message done * on channel ch. */ ch->ops->destroy(ch); g_free(private->llm); g_free(private);}static oc_ev_callback_t *mem_set_callback(class_t *class, oc_ev_callback_t f){ mbr_private_t *private; oc_ev_callback_t *ret_f; if(!class_valid(class)){ return NULL; } private = (mbr_private_t *)class->private; ret_f = private->callback; private->callback = f; return ret_f;}/* this function is a kludge, to accomodate special behaviour not * supported by 0.2 version of the API */static voidmem_set_special(class_t *class, int type){ mbr_private_t *private; if(!class_valid(class)) { return; } private = (mbr_private_t *)class->private; private->special = 1; /* turn on the special behaviour not supported by 0.2 version of the API */ return;}static gbooleanmem_is_my_nodeid(class_t *class, const oc_node_t *node){ mbr_private_t *private; if(!class_valid(class)){ return FALSE; } private = (mbr_private_t *)class->private; if (node->node_id == CLLM_GET_MYUUID(private->llm)){ return TRUE; } return FALSE;}class_t *oc_ev_memb_class(oc_ev_callback_t *fn){ mbr_private_t *private; class_t *memclass; struct IPC_CHANNEL *ch; GHashTable * attrs; static char path[] = IPC_PATH_ATTR; static char ccmfifo[] = CCMFIFO; memclass = g_malloc(sizeof(class_t)); if (!memclass){ return NULL; } private = (mbr_private_t *)g_malloc0(sizeof(mbr_private_t)); if (!private) { g_free(memclass); return NULL; } memclass->type = OC_EV_MEMB_CLASS; memclass->set_callback = mem_set_callback; memclass->handle_event = mem_handle_event; memclass->activate = mem_activate; memclass->unregister = mem_unregister; memclass->is_my_nodeid = mem_is_my_nodeid; memclass->special = mem_set_special; memclass->private = (void *)private; private->callback = fn; private->magiccookie = 0xabcdef; private->client_report = FALSE; private->special = 0; /* no special behaviour */ attrs = g_hash_table_new(g_str_hash,g_str_equal); g_hash_table_insert(attrs, path, ccmfifo); ch = ipc_channel_constructor(IPC_DOMAIN_SOCKET, attrs); g_hash_table_destroy(attrs); if(!ch) { g_free(memclass); g_free(private); return NULL; } private->channel = ch; return memclass;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -