Ejemplo n.º 1
0
// 返回发送链元素数
// -1,连接状态异常,需要清空事件
//  0, 发送链空,需要清除写事件
int connector_send(int fd) {
    connector_t *con = connector_get_ptr(fd);
    while(1) {
        send_q_t **curr = &con->send_q_head;
        send_q_t *q_entry = *curr;
        if(q_entry == NULL)
            break;
        int num = net_write_n(fd, (char *)(q_entry->send_buf) + q_entry->send_len, q_entry->buf_len - q_entry->send_len);
        logging_trace("%s:%d %d write %d bytes", con->ip, con->port, fd, num);
        if(num == 0) {
            break;
        }
        else if(num == -1) {
            con->closed_flag = 1;
            if(con->processing_count == 0)
                connector_destroy(fd);
            return -1;
        }
        else {
            (*curr)->send_len += num;
            logging_trace("%s:%d %d send_buf_len %d, send_len %d", con->ip, con->port, fd, q_entry->buf_len, q_entry->send_len);
            if(q_entry->send_len == q_entry->buf_len) {
                *curr = (*curr)->next;
                mem_free(q_entry->send_buf);
                mem_free(q_entry);
                // 发送队列计数
                con->send_q_count --;
                logging_trace("%s:%d %d send_q_count %d", con->ip, con->port, fd, con->send_q_count);
            }
        }
    }
    if(con->send_q_count == 0 && con->closing_flag && con->processing_count)
        connector_destroy(fd);
    return con->send_q_count;
}
Ejemplo n.º 2
0
// 返回-1,发送过慢异常,清空事件
// 返回 1,发送链刚刚建立,需要建立写事件
int connector_push_packet(int fd, void *data, int len) {
    connector_t *con = connector_get_ptr(fd);
    // 连接引用计数
    con->processing_count --;
    logging_trace("%s:%d %d push_packet %d bytes, processing_count %d", con->ip, con->port, fd, con->processing_count);

    if(con->closed_flag) {
        if(len)
            mem_free(data);
        if(con->processing_count == 0) {
            logging_trace("%s:%d %d check closed_flag processing_count 0", con->ip, con->port, fd);
            connector_destroy(fd);
        }
        return 0;
    }
    if(!len && con->closing_flag && con->processing_count == 0 && con->send_q_count == 0) {
        logging_trace("%s:%d %d check closing_flag processing_count 0, send_q_count 0", con->ip, con->port, fd);
        connector_destroy(fd);
        return -1;
    }
    if(!len) {
        return 0;
    }
    // 发送队列计数
    con->send_q_count ++;

    if(con->send_q_count > MAX_SEND_Q_COUNT) {
        logging_trace("%s:%d %d send_q_count %d overflow", con->ip, con->port, fd, con->send_q_count);
        con->closed_flag = 1;
        mem_free(data);
        con->send_q_count --;
        return -1;
    }

    logging_trace("%s:%d %d send_q_count %d", con->ip, con->port, fd, con->send_q_count);
    send_q_t *q_entry = (send_q_t *)mem_malloc(sizeof(send_q_t));
    q_entry->send_buf = data;
    q_entry->buf_len = len;
    q_entry->send_len = 0;
    q_entry->next = NULL;

    send_q_t **curr = &con->send_q_head;
    while(*curr) *curr = (*curr)->next;
    *curr = q_entry;
    return con->send_q_count;
}
Ejemplo n.º 3
0
Archivo: socket.c Proyecto: dpw/molerat
static void finish_connecting(void *v_c)
{
	struct connector *c = v_c;
	struct client_socket *s = c->socket;

	for (;;) {
		if (!wait_list_down(&c->connecting, 1, &c->tasklet))
			return;

		if (c->connected) {
			int fd = c->fd;
			struct watched_fd *watched_fd = c->watched_fd;
			c->fd = -1;

			connector_destroy(c);
			s->connector = NULL;

			simple_socket_set_fd(&s->base, fd, watched_fd);

			/* Access to the ops pointer is not locked.
			 * But it is fine if some threads continue to
			 * use the old client_socket_ops value. */
			s->base.base.ops = &simple_socket_ops;

			/* Tasklet got destroyed, so we are still
			   holding the associated lock. */
			mutex_unlock(&s->base.mutex);
			return;
		}
		else {
			/* Got POLLERR */
			int e;
			socklen_t len = sizeof e;
			const char *syscall = "connect";

			if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &e, &len)) {
				e = errno;
				syscall = "getsockopt";
			}

			if (e) {
				/* Stash the error and try another address */
				error_errno_val(&c->err, e, "%s", syscall);
				start_connecting(c);
			}
			/* Strange, no error.  Continue to poll. */
			else if (!watched_fd_set_interest(c->watched_fd,
						  WATCHED_FD_OUT, &c->err)) {
				simple_socket_wake_all(&c->socket->base);
			}
		}
	}
}
Ejemplo n.º 4
0
Archivo: socket.c Proyecto: dpw/molerat
static void client_socket_destroy(struct stream *gs)
{
	struct client_socket *s = (struct client_socket *)gs;
	assert(((struct socket *)gs)->ops == &client_socket_ops);

	mutex_lock(&s->base.mutex);

	if (s->connector)
		connector_destroy(s->connector);

	simple_socket_fini(&s->base);
	free(s);
}
Ejemplo n.º 5
0
// -1,连接状态异常,需要清空事件
int connector_recv(int fd) {
    connector_t *con = connector_get_ptr(fd);
    // 缓冲区满继续期望读,返回异常
    if(con->recv_len == MAX_RECV_BUF_LEN) {
        logging_trace("%s:%d %d recv_buf overflow", con->ip, con->port, fd);
        con->closed_flag = 1;
        if(con->processing_count == 0)
            connector_destroy(fd);
        return -1;
    }
    int num = net_read_n(fd, con->recv_buf + con->recv_len, MAX_RECV_BUF_LEN - con->recv_len);
    logging_trace("%s:%d %d read %d bytes", con->ip, con->port, fd, num);
    if(num == -1) {
        con->closed_flag = 1;
        if(con->processing_count == 0)
            connector_destroy(fd);
        return -1;
    }
    gettimeofday(&(con->updated_at), NULL);
    con->recv_len += num;
    logging_trace("%s:%d %d recv_len %d", con->ip, con->port, fd);
    return 0;
}
Ejemplo n.º 6
0
// -1,超时异常,需要清空事件
int connector_check_timeout(int fd, struct timeval *tv, int idle_timeout_ms) {
    connector_t *con = connector_get_ptr(fd);
    if(con->closed_flag)
        return 0;
    int milliseconds =
        1000 * (tv->tv_sec - con->updated_at.tv_sec) +
        (tv->tv_usec - con->updated_at.tv_usec) / 1000;
    if(milliseconds > idle_timeout_ms) {
        logging_trace("%s:%d %d check idle_timeout", con->ip, con->port, fd);
        con->closed_flag = 1;
        if(con->processing_count == 0)
            connector_destroy(fd);
        return -1;
    }
    return 0;
}
Ejemplo n.º 7
0
Archivo: socket.c Proyecto: dpw/molerat
static enum stream_result client_socket_close(struct stream *gs,
					      struct tasklet *t,
					      struct error *e)
{
	struct client_socket *s = (struct client_socket *)gs;

	assert(((struct socket *)gs)->ops == &client_socket_ops);
	mutex_lock(&s->base.mutex);

	if (!s->connector) {
		mutex_unlock(&s->base.mutex);
		return simple_socket_close(gs, t, e);
	}
	else {
		connector_destroy(s->connector);
		s->connector = NULL;
		mutex_unlock(&s->base.mutex);
		return STREAM_OK;
	}
}