Ejemplo n.º 1
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.º 2
0
void* write_func(void *data) {
    std::unique_ptr<TaskData> tdata((TaskData*)data);
    int epollfd = tdata->epollfd;
    epoll_event event = (tdata->event);
    CEpollSocketWatcher &socket_handler = *(tdata->watcher);

    CEpollContext *epoll_context = (CEpollContext *) 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 NULL;
    }

    if (ret == WRITE_CONN_CONTINUE) {
        event.events = EPOLLOUT;
    } else {
        event.events = EPOLLIN;
    }
    epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event);

    return NULL;
}
Ejemplo n.º 3
0
void* read_func(void *data) {
    std::unique_ptr<TaskData> tdata((TaskData*)data);
    int epollfd = tdata->epollfd;
    epoll_event event = (tdata->event);
    CEpollSocketWatcher &socket_handler = *(tdata->watcher);

    CEpollContext *epoll_context = (CEpollContext *) event.data.ptr;
    int fd = epoll_context->fd;

    int ret = socket_handler.on_readable(epollfd, event);
    if (ret == READ_CLOSE) {
        close_and_release(epollfd, event, socket_handler);
        return NULL;
    }
    if (ret == READ_CONTINUE) {
        event.events = EPOLLIN;
        epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event);
    } else if (ret == READ_OVER) { // READ_OVER
        event.events = EPOLLOUT;
        epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event);
    } else {
        LOG_ERROR("unkonw ret!");
    }

    return NULL;
}
Ejemplo n.º 4
0
int CEpollSocket::handle_writeable_event(int epollfd, epoll_event &event, CEpollSocketWatcher &socket_handler) {
    CEpollContext *epoll_context = (CEpollContext *) event.data.ptr;
    int fd = epoll_context->fd;
    epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &event);

    TaskData *tdata = new TaskData();
    tdata->epollfd = epollfd;
    tdata->event = event;
    tdata->watcher = &socket_handler;

    CTask *task = new CTask(write_func, tdata);
    int ret = m_thread_pool->add_task(task);
    if (ret != 0) {
        LOG_WARN("add write task fail:%d, we will close connect.", ret);
        close_and_release(epollfd, event, socket_handler);
    }
    return ret;
}
Ejemplo n.º 5
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.º 6
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;
			}
		}
	}
}