int skynet_multicast_castgroup(struct skynet_context * from, struct skynet_multicast_group * group, struct skynet_multicast_message *msg) { combine_queue(from, group); if (group->number == 0) { skynet_multicast_dispatch(msg, NULL, NULL); return 0; } uint32_t source = skynet_context_handle(from); skynet_multicast_copy(msg, group->number); int i; int release = 0; for (i=0;i<group->number;i++) { struct pair * p = &group->data[i]; skynet_context_send(p->ctx, msg, 0 , source, PTYPE_MULTICAST , 0); int ref = skynet_context_ref(p->ctx); if (ref == 1) { skynet_context_release(p->ctx); struct skynet_context * ctx = skynet_handle_grab(p->handle); if (ctx == NULL) { p->ctx = NULL; skynet_multicast_leavegroup(group, p->handle); ++release; } } } return group->number - release; }
static int _drop_queue(struct message_queue *q) { // todo: send message back to message source struct skynet_message msg; int s = 0; while(!skynet_mq_pop(q, &msg)) { ++s; int type = msg.sz >> HANDLE_REMOTE_SHIFT; if (type == PTYPE_MULTICAST) { assert((msg.sz & HANDLE_MASK) == 0); skynet_multicast_dispatch((struct skynet_multicast_message *)msg.data, NULL, NULL); } else { free(msg.data); } } _release(q); return s; }