예제 #1
0
static void
_dispatch_queue(struct harbor *h, struct skynet_context * context, struct msg_queue * queue, uint32_t handle,  const char name[GLOBALNAME_LENGTH] ) {
	int harbor_id = handle >> HANDLE_REMOTE_SHIFT;
	assert(harbor_id != 0);
	int fd = h->remote_fd[harbor_id];
	if (fd < 0) {
		char tmp [GLOBALNAME_LENGTH+1];
		memcpy(tmp, name , GLOBALNAME_LENGTH);
		tmp[GLOBALNAME_LENGTH] = '\0';
		skynet_error(context, "Drop message to %s (in harbor %d)",tmp,harbor_id);
		return;
	}
	struct msg * m = _pop_queue(queue);
	while (m) {
		struct remote_message_header * cookie = (struct remote_message_header *)(m->buffer + m->size - sizeof(*cookie));
		cookie->destination |= (handle & HANDLE_MASK);
		_header_to_message(cookie, (uint32_t *)cookie);
		int err = _send_package(fd, m->buffer, m->size);
		if (err) {
			close(fd);
			h->remote_fd[harbor_id] = _connect_to(context, h->remote_addr[harbor_id]);
			if (h->remote_fd[harbor_id] < 0) {
				skynet_error(context, "Reconnect to harbor %d %s failed",harbor_id, h->remote_addr[harbor_id]);
				return;
			}
		}
		free(m->buffer);
		m = _pop_queue(queue);
	}
}
예제 #2
0
static int
_send_remote(int fd, const char * buffer, size_t sz, struct remote_message_header * cookie) {
	uint32_t sz_header = htonl(sz+sizeof(*cookie));
	struct iovec part[3];

	part[0].iov_base = &sz_header;
	part[0].iov_len = 4;

	part[1].iov_base = (char *)buffer;
	part[1].iov_len = sz;

	uint32_t header[3];
	_header_to_message(cookie, header);

	part[2].iov_base = header;
	part[2].iov_len = sizeof(header);
	for (;;) {
		int err = writev(fd, part, 3);
		if (err < 0) {
			switch (errno) {
			case EAGAIN:
			case EINTR:
				continue;
			}
		}
		if (err != sz+sizeof(*cookie)+4) {
			return 1;
		}
		return 0;
	}
}
예제 #3
0
static void
_send_remote(struct skynet_context * ctx, int fd, const char * buffer, size_t sz, struct remote_message_header * cookie) {
	uint32_t sz_header = sz+sizeof(*cookie);
	uint8_t * sendbuf = (uint8_t *)skynet_malloc(sz_header+4);
	to_bigendian(sendbuf, sz_header);
	memcpy(sendbuf+4, buffer, sz);
	_header_to_message(cookie, sendbuf+4+sz);

	if (skynet_socket_send(ctx, fd, sendbuf, sz_header+4)) {
		skynet_error(ctx, "Remote send to %d error", fd);
	}
}
예제 #4
0
static void
_dispatch_queue(struct harbor *h, struct msg_queue * queue, uint32_t handle,  const char name[GLOBALNAME_LENGTH] ) {
	int harbor_id = handle >> HANDLE_REMOTE_SHIFT;
	assert(harbor_id != 0);
	struct skynet_context * context = h->ctx;
	int fd = h->remote_fd[harbor_id];
	if (fd < 0) {
		char tmp [GLOBALNAME_LENGTH+1];
		memcpy(tmp, name , GLOBALNAME_LENGTH);
		tmp[GLOBALNAME_LENGTH] = '\0';
		skynet_error(context, "Drop message to %s (in harbor %d)",tmp,harbor_id);
		return;
	}
	struct msg * m = _pop_queue(queue);
	while (m) {
		struct remote_message_header cookie;
		uint8_t *ptr = m->buffer + m->size - sizeof(cookie);
		memcpy(&cookie, ptr, sizeof(cookie));
		cookie.destination |= (handle & HANDLE_MASK);
		_header_to_message(&cookie, ptr);
		_send_package(context, fd, m->buffer, m->size);
		m = _pop_queue(queue);
	}
}