[Assorted-commits] SF.net SVN: assorted:[992] netio-bench
Brought to you by:
yangzhang
From: <yan...@us...> - 2008-10-06 22:25:21
|
Revision: 992 http://assorted.svn.sourceforge.net/assorted/?rev=992&view=rev Author: yangzhang Date: 2008-10-06 22:25:11 +0000 (Mon, 06 Oct 2008) Log Message: ----------- added network IO benchmark Added Paths: ----------- netio-bench/ netio-bench/trunk/ netio-bench/trunk/src/ netio-bench/trunk/src/Makefile netio-bench/trunk/src/epoll.cc Added: netio-bench/trunk/src/Makefile =================================================================== --- netio-bench/trunk/src/Makefile (rev 0) +++ netio-bench/trunk/src/Makefile 2008-10-06 22:25:11 UTC (rev 992) @@ -0,0 +1,9 @@ +all: epoll + +epoll: epoll.cc + g++ -I../../../cpp-commons/trunk/src/ -Wall -O3 -o $@ $< + +clean: + rm -f epoll + +.PHONY: clean Added: netio-bench/trunk/src/epoll.cc =================================================================== --- netio-bench/trunk/src/epoll.cc (rev 0) +++ netio-bench/trunk/src/epoll.cc 2008-10-06 22:25:11 UTC (rev 992) @@ -0,0 +1,106 @@ +#include <fcntl.h> +#include <stdio.h> +#include <sys/epoll.h> +#include <unistd.h> + +#include <iostream> + +#include <commons/check.h> +#include <commons/closing.h> +#include <commons/sockets.h> + +using namespace commons; +using namespace std; + +/** + * Read data from the given file descriptor until we would block (EAGAIN) or we + * hit EOF/an error. + * \return true if we hit EAGAIN, false on EOF or unexpected error. + */ +static bool +consume(int fd) { + while (true) { + char buf[1024]; + int bytes = read(fd, buf, sizeof buf); + if (bytes == -1) { + if (errno == EAGAIN) { + return true; + } else { + perror("read"); + return false; + } + } + if (bytes == 0) { + return false; + } + + // Write the data to stdout + checknneg(write(1, buf, bytes) == -1); + } +} + +int +main(int argc, char* argv[]) { + int server = tcp_listen(8080, true); + + // Make sure the fd is finally closed. + closingfd closer(server); + + // Create our epoll file descriptor + const int max_events = 16; + int epoll_fd = checknneg(epoll_create(max_events)); + + // Add our server fd to the epoll event loop + struct epoll_event event; + event.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLET; + event.data.fd = server; + checknneg(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server, &event)); + + // Execute the epoll event loop + while (true) { + struct epoll_event events[max_events]; + int num_fds = epoll_wait(epoll_fd, events, max_events, -1); + + for (int i = 0; i < num_fds; i++) { + // Case 1: Error condition + if (events[i].events & (EPOLLHUP | EPOLLERR)) { + fputs("epoll: EPOLLERR", stderr); + close(events[i].data.fd); + continue; + } + check(events[i].events & EPOLLIN); + + // Case 2: Our server is receiving a connection + if (events[i].data.fd == server) { + struct sockaddr remote_addr; + socklen_t addr_size = sizeof(remote_addr); + int connection = accept(server, &remote_addr, &addr_size); + if (connection == -1) { + if (errno != EAGAIN && errno != EWOULDBLOCK) { + perror("accept"); + } + continue; + } + + // Make the connection non-blocking + checknneg(fcntl(connection, F_SETFL, + O_NONBLOCK | fcntl(connection, F_GETFL, 0))); + + // Add the connection to our epoll loop + event.data.fd = connection; + checknneg(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, connection, + &event)); + continue; + } + + // Case 3: One of our connections has read data + if (!consume(events[i].data.fd)) { + // epoll will remove the fd from its set + // automatically when the fd is closed + close(events[i].data.fd); + } + } + } + + return 0; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |