static void _update_address(struct master *m, int harbor_id, const char * buffer, size_t sz) { if (m->remote_fd[harbor_id] >= 0) { close_harbor(m, harbor_id); } skynet_free(m->remote_addr[harbor_id]); char * addr = (char*)skynet_malloc(sz+1); memcpy(addr, buffer, sz); addr[sz] = '\0'; m->remote_addr[harbor_id] = addr; _connect_to(m, harbor_id); }
void harbor_release(struct harbor *h) { int i; for (i=1;i<REMOTE_MAX;i++) { struct slave *s = &h->s[i]; if (s->fd && s->status != STATUS_DOWN) { close_harbor(h,i); report_harbor_down(h,i); } } hash_delete(h->map); skynet_free(h); }
void harbor_release(struct harbor *h) { int i; for (i=1;i<REMOTE_MAX;i++) { struct slave *s = &h->s[i]; if (s->fd && s->status != STATUS_DOWN) { close_harbor(h,i); // don't call report_harbor_down. // never call skynet_send during module exit, because of dead lock } } hash_delete(h->map); skynet_free(h); }
static void dispatch_socket(struct master *m, const struct skynet_socket_message *msg, int sz) { int id = socket_id(m, msg->id); switch(msg->type) { case SKYNET_SOCKET_TYPE_CONNECT: assert(id); on_connected(m, id); break; case SKYNET_SOCKET_TYPE_ERROR: skynet_error(m->ctx, "socket error on harbor %d", id); // go though, close socket case SKYNET_SOCKET_TYPE_CLOSE: close_harbor(m, id); break; default: skynet_error(m->ctx, "Invalid socket message type %d", msg->type); break; } }
static int _mainloop(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) { struct harbor * h = (struct harbor *)ud; switch (type) { case PTYPE_SOCKET: { const struct skynet_socket_message * message = (const struct skynet_socket_message *)msg; switch(message->type) { case SKYNET_SOCKET_TYPE_DATA: skynet_free(message->buffer); skynet_error(context, "recv invalid socket message (size=%d)", message->ud); break; case SKYNET_SOCKET_TYPE_ACCEPT: skynet_error(context, "recv invalid socket accept message"); break; case SKYNET_SOCKET_TYPE_ERROR: case SKYNET_SOCKET_TYPE_CLOSE: close_harbor(h, message->id); break; case SKYNET_SOCKET_TYPE_CONNECT: open_harbor(h, message->id); break; } return 0; } case PTYPE_HARBOR: { // remote message in const char * cookie = (const char *)msg; cookie += sz - 12; struct remote_message_header header; _message_to_header((const uint32_t *)cookie, &header); if (header.source == 0) { if (header.destination < REMOTE_MAX) { // 1 byte harbor id (0~255) // update remote harbor address //char ip [sz - 11]; char ip [100]; memcpy(ip, msg, sz-12); ip[sz-11] = '\0'; _update_remote_address(h, header.destination, ip); } else { // update global name if (sz - 12 > GLOBALNAME_LENGTH) { //char name[sz-11]; char name[100]; memcpy(name, msg, sz-12); name[sz-11] = '\0'; skynet_error(context, "Global name is too long %s", name); } _update_remote_name(h, (const char*)msg, header.destination); } } else { uint32_t destination = header.destination; int type = (destination >> HANDLE_REMOTE_SHIFT) | PTYPE_TAG_DONTCOPY; destination = (destination & HANDLE_MASK) | ((uint32_t)h->id << HANDLE_REMOTE_SHIFT); skynet_send(context, header.source, destination, type, (int)header.session, (void *)msg, sz-12); return 1; } return 0; } case PTYPE_SYSTEM: { // register name message const struct remote_message *rmsg = (const struct remote_message *)msg; assert (sz == sizeof(rmsg->destination)); _remote_register_name(h, rmsg->destination.name, rmsg->destination.handle); return 0; } default: { // remote message out const struct remote_message *rmsg = (const struct remote_message *)msg; if (rmsg->destination.handle == 0) { if (_remote_send_name(h, source , rmsg->destination.name, type, session, (const char*)rmsg->message, rmsg->sz)) { return 0; } } else { if (_remote_send_handle(h, source , rmsg->destination.handle, type, session, (const char *)rmsg->message, rmsg->sz)) { return 0; } } skynet_free((void *)rmsg->message); return 0; } } }