From 7492bfbcb6d5e4733ab20d8b41ff02f38dfbd143 Mon Sep 17 00:00:00 2001 From: fengbojiang Date: Thu, 6 Apr 2023 21:53:02 +0800 Subject: [PATCH] Add helloworld_stack_epoll for demo. --- example/Makefile | 3 +- example/main_stack_epoll.c | 202 +++++++++++++++++++++++++++++++++++++ 2 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 example/main_stack_epoll.c diff --git a/example/Makefile b/example/Makefile index 5c52df9a6..2ca45b0fc 100644 --- a/example/Makefile +++ b/example/Makefile @@ -10,7 +10,7 @@ endif PKGCONF ?= pkg-config -CFLAGS += -O -gdwarf-2 $(shell $(PKGCONF) --cflags libdpdk) +CFLAGS += -O0 -g -gdwarf-2 $(shell $(PKGCONF) --cflags libdpdk) LIBS+= $(shell $(PKGCONF) --static --libs libdpdk) LIBS+= -L${FF_PATH}/lib -Wl,--whole-archive,-lfstack,--no-whole-archive @@ -20,6 +20,7 @@ TARGET="helloworld" all: cc ${CFLAGS} -DINET6 -o ${TARGET} main.c ${LIBS} cc ${CFLAGS} -o ${TARGET}_epoll main_epoll.c ${LIBS} + cc ${CFLAGS} -I ../adapter -o ${TARGET}_stack_epoll main_stack_epoll.c ${LIBS} .PHONY: clean clean: diff --git a/example/main_stack_epoll.c b/example/main_stack_epoll.c new file mode 100644 index 000000000..e3278f1dc --- /dev/null +++ b/example/main_stack_epoll.c @@ -0,0 +1,202 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_WORKERS 128 +pthread_t hworker[MAX_WORKERS]; +pthread_spinlock_t worker_lock; +#define MAX_EVENTS 512 + +static int exit_flag = 0; + +char html[] = +"HTTP/1.1 200 OK\r\n" +"Server: F-Stack\r\n" +"Date: Sat, 25 Feb 2017 09:26:33 GMT\r\n" +"Content-Type: text/html\r\n" +"Content-Length: 438\r\n" +"Last-Modified: Tue, 21 Feb 2017 09:44:03 GMT\r\n" +"Connection: keep-alive\r\n" +"Accept-Ranges: bytes\r\n" +"\r\n" +"\r\n" +"\r\n" +"\r\n" +"Welcome to F-Stack!\r\n" +"\r\n" +"\r\n" +"\r\n" +"

Welcome to F-Stack!

\r\n" +"\r\n" +"

For online documentation and support please refer to\r\n" +"F-Stack.org.
\r\n" +"\r\n" +"

Thank you for using F-Stack.

\r\n" +"\r\n" +""; + +void sig_term(int sig) +{ + printf("we caught signal %d, to exit helloworld\n", sig); + exit_flag = 1; + return; +} + +void *loop(void *arg) +{ + struct epoll_event ev; + struct epoll_event events[MAX_EVENTS]; + int epfd; + int sockfd; + int thread_id; + + thread_id = *(int *)arg; + pthread_spin_unlock(&worker_lock); + + printf("start thread %d\n", thread_id); + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + printf("thread %d, sockfd:%d\n", thread_id, sockfd); + if (sockfd < 0) { + printf("thread %d, ff_socket failed\n", thread_id); + exit(1); + } + + int on = 1; + ioctl(sockfd, FIONBIO, &on); + + struct sockaddr_in my_addr; + bzero(&my_addr, sizeof(my_addr)); + my_addr.sin_family = AF_INET; + my_addr.sin_port = htons(80); + my_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + int ret = bind(sockfd, (const struct sockaddr *)&my_addr, sizeof(my_addr)); + if (ret < 0) { + printf("thread %d, ff_bind failed\n", thread_id); + exit(1); + } + + ret = listen(sockfd, MAX_EVENTS); + if (ret < 0) { + printf("thread %d, ff_listen failed\n", thread_id); + exit(1); + } + + epfd = epoll_create(0); + if (epfd <= 0) { + printf("thread %d, ff_epoll_create failed, errno:%d, %s\n", + thread_id, errno, strerror(errno)); + exit(1); + } + ev.data.fd = sockfd; + ev.events = EPOLLIN; + epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev); + + /* Wait for events to happen */ + while (!exit_flag) { + int nevents = epoll_wait(epfd, events, MAX_EVENTS, 100); + if (nevents <= 0) { + if (nevents) { + printf("thread %d, hello world epoll wait ret %d, errno:%d, %s\n", + thread_id, nevents, errno, strerror(errno)); + } + //usleep(100); + sleep(1); + } + printf("thread %d, get nevents:%d\n", thread_id, nevents); + int i; + + for (i = 0; i < nevents; ++i) { + /* Handle new connect */ + if (events[i].data.fd == sockfd) { + while (1) { + int nclientfd = accept(sockfd, NULL, NULL); + if (nclientfd < 0) { + break; + } + + /* Add to event list */ + ev.data.fd = nclientfd; + ev.events = EPOLLIN; + if (epoll_ctl(epfd, EPOLL_CTL_ADD, nclientfd, &ev) != 0) { + printf("thread %d, ff_epoll_ctl failed:%d, %s\n", + thread_id, errno, strerror(errno)); + break; + } + } + } else { + if (events[i].events & EPOLLERR ) { + /* Simply close socket */ + epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, NULL); + close(events[i].data.fd); + } else if (events[i].events & EPOLLIN) { + char buf[256]; + size_t readlen = read( events[i].data.fd, buf, sizeof(buf)); + if(readlen > 0) { + write( events[i].data.fd, html, sizeof(html) - 1); + } else { + epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, NULL); + close(events[i].data.fd); + } + } else { + printf("thread %d, unknown event: %8.8X\n", events[i].events); + } + } + } + } +} + +int main(int argc, char * argv[]) +{ + int i, worker_num; + + signal(SIGTERM, sig_term); + + if (argc == 1) { + worker_num = 1; + } else { + worker_num = atoi(argv[1]); + } + printf("to init %d workers.\n", worker_num); + + pthread_spin_init(&worker_lock, PTHREAD_PROCESS_SHARED); + + for (i = 0; i < worker_num; i++) { + pthread_spin_lock(&worker_lock); + if(pthread_create(&hworker[i], NULL, loop, (void *)&i) < 0) { + printf("create loop thread failed., errno:%d/%s\n", + errno, strerror(errno)); + pthread_spin_unlock(&worker_lock); + pthread_spin_destroy(&worker_lock); + return -1; + } + sleep(5); + } + + for (i = 0; i < worker_num; i++) { + pthread_join(hworker[i], NULL); + } + + pthread_spin_destroy(&worker_lock); + + return 0; +}