Commit c33578329ce7476f9fa0a667eb864abcecc45a09
1 parent
fb0dd8ad
changed from select(UNIX) to poll(POSIX)
Showing
8 changed files
with
118 additions
and
94 deletions
... | ... | @@ -2,20 +2,24 @@ |
2 | 2 | #define __SERVER_H__ |
3 | 3 | |
4 | 4 | #include <stdio.h> /* for printf() and fprintf() */ |
5 | -#include <sys/select.h> /* for select system call and related */ | |
5 | +#include <poll.h> /* for select system call and related */ | |
6 | 6 | |
7 | 7 | #include "socket.h" |
8 | 8 | #include "logger.h" |
9 | 9 | #include "cclass.h" |
10 | 10 | |
11 | +#define POLL_FD_NSIZE 1024 | |
12 | +#define POLL_FD_SIZE (sizeof(struct pollfd) * POLL_FD_NSIZE) | |
13 | +#define POLL_FD_MOVE(idx) (sizeof(struct pollfd) * (POLL_FD_NSIZE-(idx)+1)) | |
14 | + | |
11 | 15 | |
12 | 16 | typedef void (*server_read_hook)(const char *); |
13 | 17 | |
14 | 18 | CLASS(SERVER) { |
15 | - LOGGER logger; | |
16 | - SOCK sock; | |
17 | - unsigned int max_fd; | |
18 | - fd_set fdset; | |
19 | + LOGGER logger; | |
20 | + SOCK sock; | |
21 | + nfds_t nfds; | |
22 | + struct pollfd fds[POLL_FD_NSIZE]; | |
19 | 23 | |
20 | 24 | struct { |
21 | 25 | SOCK sock; |
... | ... | @@ -23,14 +27,13 @@ CLASS(SERVER) { |
23 | 27 | char * rbuf; |
24 | 28 | unsigned int rpos; |
25 | 29 | unsigned int wpos; |
26 | - } conns[FD_SETSIZE]; | |
30 | + } conns[POLL_FD_NSIZE]; | |
27 | 31 | |
28 | 32 | server_read_hook read_hook; |
29 | 33 | }; |
30 | 34 | |
31 | 35 | void server_run(SERVER this); |
32 | -//void server_close(SERVER this); | |
33 | -//void server_shutdown(SERVER this); | |
36 | +void server_close_conn(SERVER this, unsigned int handle); | |
34 | 37 | |
35 | 38 | #endif // __SERVER_H__ |
36 | 39 | ... | ... |
1 | -#include <sys/select.h> /* for select system call and related */ | |
1 | +#include <poll.h> /* for select system call and related */ | |
2 | 2 | #include <string.h> /* for memset and stuff */ |
3 | 3 | #include <stdlib.h> /* for getopt */ |
4 | 4 | |
... | ... | @@ -8,7 +8,6 @@ |
8 | 8 | #include "logger.h" |
9 | 9 | #include "cclass.h" |
10 | 10 | |
11 | - | |
12 | 11 | INIT_CLASS(SERVER); |
13 | 12 | |
14 | 13 | __construct(SERVER) |
... | ... | @@ -20,27 +19,23 @@ __construct(SERVER) |
20 | 19 | port = va_arg(* params, int); |
21 | 20 | backlog = va_arg(* params, unsigned int); |
22 | 21 | |
23 | - FD_ZERO(&(this->fdset)); | |
24 | - | |
25 | - this->sock = new(SOCK, port); | |
22 | + this->sock = new(SOCK, this->logger, port); | |
26 | 23 | sock_listen(this->sock, backlog); |
27 | 24 | |
28 | - this->max_fd = this->sock->handle; | |
29 | - FD_SET(this->sock->handle, &(this->fdset)); | |
25 | + (this->fds)[0].fd = this->sock->handle; | |
26 | + (this->fds)[0].events = POLLIN; | |
27 | + this->nfds = 1; | |
30 | 28 | } |
31 | 29 | |
32 | 30 | __destruct(SERVER) |
33 | 31 | { |
34 | 32 | int i; |
35 | 33 | |
36 | - for (i=3; i<=this->max_fd; i++) { | |
37 | - if (FD_ISSET(i, &(this->fdset)) && i != this->sock->handle) { | |
38 | - /* | |
39 | - * @TODO do some finalization...buffer handling...etc. | |
40 | - */ | |
41 | - delete(&(this->conns[i]).sock); | |
42 | - FD_CLR(i, &(this->fdset)); | |
43 | - } | |
34 | + for (i=1; i<this->nfds; i++) { | |
35 | + /* | |
36 | + * @TODO do some finalization...buffer handling...etc. | |
37 | + */ | |
38 | + delete(&(this->conns[i]).sock); | |
44 | 39 | } |
45 | 40 | |
46 | 41 | delete(&this->sock); | ... | ... |
src/server_close_conn.c
0 → 100644
1 | -#include <sys/select.h> /* for select system call and related */ | |
1 | +#include <poll.h> /* for select system call and related */ | |
2 | 2 | #include <string.h> /* for memset and stuff */ |
3 | 3 | #include <stdlib.h> /* for exit */ |
4 | 4 | #include <errno.h> /* for errno */ |
... | ... | @@ -13,17 +13,14 @@ |
13 | 13 | #define MAX(x,y) ((x) > (y) ? (x) : (y)) |
14 | 14 | |
15 | 15 | static |
16 | -fd_set | |
16 | +int | |
17 | 17 | server_select(SERVER this) { |
18 | - fd_set rfds; | |
19 | - | |
20 | - memcpy(&rfds, &(this->fdset), sizeof(fd_set)); | |
18 | + int events; | |
21 | 19 | |
22 | 20 | /* |
23 | 21 | * wait for handles to become ready |
24 | 22 | */ |
25 | - if (-1 == select((this->max_fd)+1, &rfds, NULL, NULL, NULL)) | |
26 | - { | |
23 | + if (-1 == (events = poll(this->fds, this->nfds, -1))) { | |
27 | 24 | switch (errno) { |
28 | 25 | default: |
29 | 26 | case EBADF: |
... | ... | @@ -36,56 +33,48 @@ server_select(SERVER this) { |
36 | 33 | logger_log(this->logger, LOGGER_CRIT, |
37 | 34 | "select systemcall failed: [%s] - service terminated", |
38 | 35 | strerror(errno)); |
39 | - exit(EXIT_FAILURE); /* @TODO do real shutdown here */ | |
36 | + //exit(EXIT_FAILURE); /* @TODO do real shutdown here */ | |
40 | 37 | } |
41 | 38 | } |
42 | 39 | |
43 | - return rfds; | |
40 | + return events; | |
44 | 41 | } |
45 | 42 | |
46 | 43 | static |
47 | 44 | void |
48 | -server_handle_accept(SERVER this, fd_set * rfds) | |
45 | +server_handle_accept(SERVER this) | |
49 | 46 | { |
50 | - if (FD_ISSET(this->sock->handle, rfds)) { | |
51 | - int fd; | |
47 | + if (0 != ((this->fds)[0].revents & POLLIN)) { | |
52 | 48 | char remoteAddr[16] = ""; |
53 | 49 | SOCK acc; |
54 | 50 | |
55 | 51 | acc = sock_accept(this->sock, remoteAddr); |
56 | 52 | |
57 | 53 | if (-1 != acc->handle) { |
58 | - ((this->conns)[acc->handle].sock)->handle = fd; // save the socket handle | |
59 | - FD_SET(fd, &(this->fdset)); | |
60 | - this->max_fd = MAX(fd, this->max_fd); | |
54 | + (this->conns)[this->nfds].sock = acc; // save the socket handle | |
55 | + (this->fds)[this->nfds].fd = acc->handle; | |
56 | + (this->fds)[this->nfds].events = POLLIN; | |
57 | + this->nfds++; | |
61 | 58 | } else { |
62 | 59 | delete(&acc); |
63 | 60 | } |
64 | 61 | |
65 | - FD_CLR(this->sock->handle, rfds); | |
62 | + (this->fds)[0].revents |= POLLIN; | |
66 | 63 | } |
67 | 64 | } |
68 | 65 | |
69 | 66 | static |
70 | -void | |
71 | -server_close_conn(SERVER this, unsigned int handle) | |
72 | -{ | |
73 | - delete(&((this->conns)[handle].sock)); | |
74 | - FD_CLR(handle, &(this->fdset)); | |
75 | -} | |
76 | - | |
77 | -static | |
78 | 67 | int |
79 | -server_read(SERVER this, fd_set * rfds) | |
68 | +server_read(SERVER this) | |
80 | 69 | { |
81 | 70 | unsigned int i; |
82 | - size_t _read; | |
83 | - char buffer[1024]; | |
71 | + size_t _read; | |
72 | + char buffer[1024]; | |
84 | 73 | |
85 | - for (i=3; i<=this->max_fd; i++) { | |
86 | - if (FD_ISSET(i, rfds)) { | |
74 | + for (i=1; i<this->nfds; i++) { | |
75 | + if (0 != ((this->fds)[i].revents & POLLIN)) { | |
87 | 76 | memset(buffer, 0, 1024); |
88 | - switch (_read = read(i, buffer, 1023)) { | |
77 | + switch (_read = read((this->fds)[i].fd, buffer, 1023)) { | |
89 | 78 | case 0: |
90 | 79 | /* |
91 | 80 | * normal close: write remaining data |
... | ... | @@ -101,6 +90,7 @@ server_read(SERVER this, fd_set * rfds) |
101 | 90 | break; |
102 | 91 | |
103 | 92 | default: |
93 | + (this->fds)[i].revents |= POLLIN; | |
104 | 94 | if (NULL != this->read_hook) { |
105 | 95 | this->read_hook(buffer); |
106 | 96 | } |
... | ... | @@ -116,24 +106,27 @@ void |
116 | 106 | server_run(SERVER this) |
117 | 107 | { |
118 | 108 | /* |
119 | - * @TODO again a hint...add verbosity to logger.... | |
109 | + * @TODO again...add verbosity to logger.... | |
120 | 110 | */ |
121 | 111 | logger_log(this->logger, LOGGER_INFO, "service started"); |
122 | 112 | |
123 | 113 | while (!doShutdown) /* until error or signal */ |
124 | 114 | { |
125 | - fd_set rfds; | |
126 | - int i; | |
127 | - | |
128 | - rfds = server_select(this); | |
115 | + int events; | |
116 | + /* | |
117 | + * @TODO take return value of poll into account with | |
118 | + * further handling! | |
119 | + */ | |
120 | + events = server_select(this); | |
121 | + if (doShutdown) break; | |
129 | 122 | |
130 | 123 | /* |
131 | 124 | * handle accept |
132 | 125 | */ |
133 | - server_handle_accept(this, &rfds); | |
126 | + server_handle_accept(this); | |
134 | 127 | |
135 | 128 | /* handle reads */ |
136 | - server_read(this, &rfds); | |
129 | + server_read(this); | |
137 | 130 | } |
138 | 131 | } |
139 | 132 | ... | ... |
... | ... | @@ -32,17 +32,9 @@ sock_accept(SOCK this, char remoteAddr[16]) |
32 | 32 | logger_log(this->logger, LOGGER_WARNING, |
33 | 33 | "error acception connection: %s", strerror(errno)); |
34 | 34 | } else { |
35 | - strncpy (remoteAddr, inet_ntoa((sock->addr).sin_addr), sizeof(remoteAddr)-1); | |
36 | - } | |
37 | - | |
38 | - /* clntSock is connected to a client! */ | |
39 | - /** | |
40 | - * @TODO add verbosity level to logger | |
41 | - */ | |
42 | -// if (0 != this->logger->verbose) { | |
43 | 35 | logger_log(this->logger, LOGGER_INFO, |
44 | - "handling client %s\n", inet_ntoa((this->addr).sin_addr)); | |
45 | -// } | |
36 | + "handling client %s\n", inet_ntoa((sock->addr).sin_addr)); | |
37 | + } | |
46 | 38 | |
47 | 39 | return sock; |
48 | 40 | } | ... | ... |
... | ... | @@ -4,18 +4,24 @@ TESTS_ENVIRONMENT = valgrind --error-exitcode=123 --leak-check=full --quiet |
4 | 4 | TESTS = cclassTest loggerTest socketTest serverTest |
5 | 5 | check_PROGRAMS = cclassTest loggerTest socketTest serverTest |
6 | 6 | |
7 | -SOURCES = runtest.c ../src/cclass.c | |
7 | +COMMON = runtest.c ../src/cclass.c | |
8 | +CCLASS = $(COMMON) mock/class.c | |
9 | +LOGGER = $(COMMON) ../src/logger.c | |
10 | +SOCKET = $(LOGGER) ../src/socket.c ../src/socket_listen.c \ | |
11 | + ../src/socket_accept.c ../src/socket_connect.c | |
12 | +SERVER = $(SOCKET) ../src/server.c ../src/server_run.c \ | |
13 | + ../src/server_close_conn.c ../src/signalHandling.c | |
8 | 14 | |
9 | -cclassTest_SOURCES = $(SOURCES) cclassTest.c mock/class.c | |
15 | +cclassTest_SOURCES = $(CCLASS) cclassTest.c | |
10 | 16 | cclassTest_CFLAGS = -Wall -ggdb -O0 -finline-functions -I ../include -I .. -I . |
11 | 17 | |
12 | -loggerTest_SOURCES = $(SOURCES) loggerTest.c ../src/logger.c | |
18 | +loggerTest_SOURCES = $(LOGGER) loggerTest.c | |
13 | 19 | loggerTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . |
14 | 20 | |
15 | -socketTest_SOURCES = $(SOURCES) socketTest.c ../src/logger.c ../src/socket.c ../src/socket_listen.c ../src/socket_accept.c ../src/socket_connect.c | |
21 | +socketTest_SOURCES = $(SOCKET) socketTest.c | |
16 | 22 | socketTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . |
17 | 23 | |
18 | -serverTest_SOURCES = $(SOURCES) serverTest.c ../src/logger.c ../src/socket.c ../src/socket_listen.c ../src/socket_accept.c ../src/server.c ../src/server_run.c ../src/signalHandling.c | |
24 | +serverTest_SOURCES = $(SERVER) serverTest.c | |
19 | 25 | serverTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . |
20 | 26 | |
21 | 27 | EXTRA_DIST = runtest.h mock/class.h | ... | ... |
1 | 1 | #include <stdio.h> |
2 | 2 | #include <stdlib.h> |
3 | +#include <unistd.h> | |
4 | +#include <signal.h> | |
3 | 5 | |
4 | 6 | #include "runtest.h" |
5 | 7 | #include "logger.h" |
6 | 8 | #include "cclass.h" |
7 | 9 | #include "server.h" |
10 | +#include "signalHandling.h" | |
8 | 11 | |
9 | 12 | |
10 | -#define TEST_PORT 11212 | |
13 | +#define TEST_PORT 11218 | |
14 | +#define TEST_DATA "test" | |
11 | 15 | |
12 | 16 | |
13 | -int level = -1; | |
14 | -char * msg = NULL; | |
15 | -char * buffer = NULL; | |
17 | +int level = -1; | |
18 | +char msg[1024]; | |
19 | +char buffer[1024]; | |
16 | 20 | |
17 | 21 | static void |
18 | 22 | read_hook(const char * _buffer) |
19 | 23 | { |
20 | 24 | if (NULL != _buffer) { |
21 | - buffer = malloc(strlen(_buffer) + 1); | |
22 | - strcpy(buffer, _buffer); | |
25 | + strncpy(buffer, _buffer, 1023); | |
23 | 26 | } |
27 | + | |
28 | + doShutdown = 1; | |
24 | 29 | } |
25 | 30 | |
26 | 31 | static void |
27 | 32 | logfnct_mock(int _level, const char * _msg) |
28 | 33 | { |
29 | 34 | level = _level; |
30 | - msg = malloc(strlen(_msg) + 1); | |
31 | - strcpy(msg, _msg); | |
35 | + strncpy(msg, _msg, 1023); | |
32 | 36 | } |
33 | 37 | |
34 | 38 | const char testname[] = "serverTest"; |
... | ... | @@ -48,7 +52,6 @@ __setUp() |
48 | 52 | ASSERT_INSTANCE_OF(LOGGER, server->logger); |
49 | 53 | ASSERT_INSTANCE_OF(SOCK, server->sock); |
50 | 54 | ASSERT_EQUAL(TEST_PORT, server->sock->port); |
51 | - ASSERT_EQUAL(server->max_fd, server->sock->handle); | |
52 | 55 | |
53 | 56 | server->read_hook = read_hook; |
54 | 57 | |
... | ... | @@ -62,9 +65,9 @@ __tearDown() |
62 | 65 | { |
63 | 66 | level = -1; |
64 | 67 | |
65 | - if (NULL != msg) { | |
66 | - free(msg); | |
67 | - msg = NULL; | |
68 | + if (NULL != server) { | |
69 | + ASSERT_OBJECT(server); | |
70 | + delete(&server); | |
68 | 71 | } |
69 | 72 | |
70 | 73 | if (NULL != logger) { |
... | ... | @@ -72,11 +75,6 @@ __tearDown() |
72 | 75 | delete(&logger); |
73 | 76 | } |
74 | 77 | |
75 | - if (NULL != server) { | |
76 | - ASSERT_OBJECT(server); | |
77 | - delete(&server); | |
78 | - } | |
79 | - | |
80 | 78 | return TEST_OK; |
81 | 79 | } |
82 | 80 | int (* const tearDown)() = __tearDown; |
... | ... | @@ -85,6 +83,32 @@ static |
85 | 83 | int |
86 | 84 | testDummy() |
87 | 85 | { |
86 | + SOCK con; | |
87 | + pid_t pid; | |
88 | + int status; | |
89 | + | |
90 | + pid = fork(); | |
91 | + | |
92 | + switch(pid) { | |
93 | + case 0: | |
94 | + con = new(SOCK, logger, TEST_PORT); | |
95 | + sleep(1); | |
96 | + sock_connect(con, "127.0.0.1"); | |
97 | + write(con->handle, TEST_DATA, strlen(TEST_DATA)+1); | |
98 | + delete(&con); | |
99 | + __tearDown(); | |
100 | + exit(EXIT_SUCCESS); | |
101 | + | |
102 | + case -1: | |
103 | + return TEST_FAILED; | |
104 | + | |
105 | + default: | |
106 | + init_signals(); | |
107 | + server_run(server); | |
108 | + } | |
109 | + | |
110 | + ASSERT_STRING_EQUAL(TEST_DATA, buffer); | |
111 | + | |
88 | 112 | return TEST_OK; |
89 | 113 | } |
90 | 114 | ... | ... |
... | ... | @@ -8,7 +8,7 @@ |
8 | 8 | #include "socket.h" |
9 | 9 | |
10 | 10 | |
11 | -#define TEST_PORT 11212 | |
11 | +#define TEST_PORT 11213 | |
12 | 12 | |
13 | 13 | |
14 | 14 | int level = -1; |
... | ... | @@ -98,7 +98,6 @@ testAccept() |
98 | 98 | delete(&con); |
99 | 99 | __tearDown(); |
100 | 100 | exit(EXIT_SUCCESS); |
101 | - break; | |
102 | 101 | |
103 | 102 | case -1: |
104 | 103 | return TEST_FAILED; | ... | ... |
Please
register
or
login
to post a comment