Ejemplo n.º 1
0
int EpollSocket::handle_accept_event(int &epollfd, epoll_event &event, EpollSocketWatcher &socket_handler) {
    int sockfd = event.data.fd;

    std::string client_ip;
    int conn_sock = accept_socket(sockfd, client_ip);
    if (conn_sock == -1) {
        return -1;
    }
    setNonblocking(conn_sock);
    LOG_DEBUG("get accept socket which listen fd:%d, conn_sock_fd:%d", sockfd, conn_sock);

    EpollContext *epoll_context = new EpollContext();
    epoll_context->fd = conn_sock;
    epoll_context->client_ip = client_ip;

    socket_handler.on_accept(*epoll_context);

    struct epoll_event conn_sock_ev;
    conn_sock_ev.events = EPOLLIN | EPOLLET;
    conn_sock_ev.data.ptr = epoll_context;

    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &conn_sock_ev) == -1) {
        perror("epoll_ctl: conn_sock");
        exit(EXIT_FAILURE);
    }

    return 0;
}
Ejemplo n.º 2
0
int EpollSocket::handle_readable_event(int &epollfd, epoll_event &event, EpollSocketWatcher &socket_handler) {
    EpollContext *epoll_context = (EpollContext *) event.data.ptr;
    int fd = epoll_context->fd;

    int buffer_size = SS_READ_BUFFER_SIZE;
    char read_buffer[buffer_size];
    memset(read_buffer, 0, buffer_size);

    int read_size = recv(fd, read_buffer, buffer_size, 0);

    int handle_ret = 0;
    if(read_size > 0) {
        LOG_DEBUG("read success which read size:%d", read_size);
        handle_ret = socket_handler.on_readable(*epoll_context, read_buffer, buffer_size, read_size);
    }

    if(read_size <= 0 /* connect close or io error*/ || handle_ret < 0) {
        close_and_release(epollfd, event, socket_handler);
        return 0;
    }

    if (handle_ret == READ_CONTINUE) {
        event.events = EPOLLIN | EPOLLET;
    } else {
        event.events = EPOLLOUT | EPOLLET;
    }
    epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &event);
    return 0;
}
Ejemplo n.º 3
0
int EpollSocket::handle_writeable_event(int &epollfd, epoll_event &event, EpollSocketWatcher &socket_handler) {
    EpollContext *epoll_context = (EpollContext *) event.data.ptr;
    int fd = epoll_context->fd;
    LOG_DEBUG("start write data");

    int ret = socket_handler.on_writeable(*epoll_context);
    if(ret == WRITE_CONN_CLOSE) {
        close_and_release(epollfd, event, socket_handler);
        return 0;
    }

    if (ret == WRITE_CONN_CONTINUE) {
        event.events = EPOLLOUT | EPOLLET;
    } else {
        event.events = EPOLLIN | EPOLLET;
    }
    epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &event);
    return 0;
}
Ejemplo n.º 4
0
int EpollSocket::close_and_release(int &epollfd, epoll_event &epoll_event, EpollSocketWatcher &socket_handler) {
	LOG_INFO("connect close");

	EpollContext *hc = (EpollContext *) epoll_event.data.ptr;

	socket_handler.on_close(*hc);

	int fd = hc->fd;
	epoll_event.events = EPOLLIN | EPOLLOUT | EPOLLET;
	epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &epoll_event);

	if(epoll_event.data.ptr != NULL) {
		delete (EpollContext *) epoll_event.data.ptr;
		epoll_event.data.ptr = NULL;
	}

	int ret = close(fd);
	LOG_DEBUG("connect close complete which fd:%d, ret:%d", fd, ret);
	return 0;
}
Ejemplo n.º 5
0
int EpollSocket::start_epoll(int port, EpollSocketWatcher &socket_handler, int backlog) {
	int sockfd = this->listen_on(port, backlog);

	struct epoll_event ev;
	int epollfd = epoll_create(10);
	if (epollfd == -1) {
		perror("epoll_create");
		exit(EXIT_FAILURE);
	}

	ev.events = EPOLLIN;
	ev.data.fd = sockfd;
	if(epoll_ctl(epollfd, EPOLL_CTL_ADD, sockfd, &ev) == -1) {
		perror("epoll_ctl: listen_sock");
		exit(EXIT_FAILURE);
	}

	epoll_event events[10];

	while(1) {
		int fds_num = epoll_wait(epollfd, events, 10, -1);
		if(fds_num == -1) {
			perror("epoll_pwait");
			exit(EXIT_FAILURE);
		}

		for (int i = 0; i < fds_num; i++) {
			if(events[i].data.fd == sockfd) {
				int conn_sock = accept_socket(sockfd);
				setNonblocking(conn_sock);
				LOG_DEBUG("get accept socket which listen fd:%d, conn_sock_fd:%d", sockfd, conn_sock);

				EpollContext *epoll_context = new EpollContext();
				epoll_context->fd = conn_sock;

				socket_handler.on_accept(*epoll_context);

				epoll_event conn_sock_ev;
				conn_sock_ev.events = EPOLLIN | EPOLLET;
				conn_sock_ev.data.ptr = epoll_context;

				if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &conn_sock_ev) == -1) {
				   perror("epoll_ctl: conn_sock");
				   exit(EXIT_FAILURE);
				}

			} else if(events[i].events & EPOLLIN ){ // readable
				EpollContext *epoll_context = (EpollContext *) events[i].data.ptr;
				int fd = epoll_context->fd;

				int buffer_size = 1024;
				char read_buffer[buffer_size];
				memset(read_buffer, 0, buffer_size);
				int read_size = 0;

				while((read_size = recv(fd, read_buffer, buffer_size, 0)) > 0) {
					LOG_DEBUG("read success which read size:%d", read_size);

					int ret = socket_handler.on_readable(*epoll_context, read_buffer, buffer_size, read_size);
					if(ret != 0) {
						close_and_release(epollfd, events[i], socket_handler);
						continue;
					}
					memset(read_buffer, 0, buffer_size); // reset buffer for next read
				}

				if(read_size == 0 /* connect close*/ || (read_size == -1 && errno != EAGAIN) /* io error*/) {
					LOG_DEBUG("read_size not normal which size:%d", read_size);
					close_and_release(epollfd, events[i], socket_handler);
					continue;
				}

				events[i].events = EPOLLOUT | EPOLLET;
				epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &events[i]);

			} else if(events[i].events & EPOLLOUT) { // writeable
				EpollContext *epoll_context = (EpollContext *) events[i].data.ptr;
				int fd = epoll_context->fd;
				LOG_DEBUG("start write data");

				int ret = socket_handler.on_writeable(*epoll_context);
				if(ret != 0) {
					close_and_release(epollfd, events[i], socket_handler);
					continue;
				}

				events[i].events = EPOLLIN | EPOLLET;
				epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &events[i]);
			} else {
				LOG_INFO("unkonw events :%d", events[i].events);
				continue;
			}
		}
	}
}