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,20 +2,24 @@ | ||
2 | #define __SERVER_H__ | 2 | #define __SERVER_H__ |
3 | 3 | ||
4 | #include <stdio.h> /* for printf() and fprintf() */ | 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 | #include "socket.h" | 7 | #include "socket.h" |
8 | #include "logger.h" | 8 | #include "logger.h" |
9 | #include "cclass.h" | 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 | typedef void (*server_read_hook)(const char *); | 16 | typedef void (*server_read_hook)(const char *); |
13 | 17 | ||
14 | CLASS(SERVER) { | 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 | struct { | 24 | struct { |
21 | SOCK sock; | 25 | SOCK sock; |
@@ -23,14 +27,13 @@ CLASS(SERVER) { | @@ -23,14 +27,13 @@ CLASS(SERVER) { | ||
23 | char * rbuf; | 27 | char * rbuf; |
24 | unsigned int rpos; | 28 | unsigned int rpos; |
25 | unsigned int wpos; | 29 | unsigned int wpos; |
26 | - } conns[FD_SETSIZE]; | 30 | + } conns[POLL_FD_NSIZE]; |
27 | 31 | ||
28 | server_read_hook read_hook; | 32 | server_read_hook read_hook; |
29 | }; | 33 | }; |
30 | 34 | ||
31 | void server_run(SERVER this); | 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 | #endif // __SERVER_H__ | 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 | #include <string.h> /* for memset and stuff */ | 2 | #include <string.h> /* for memset and stuff */ |
3 | #include <stdlib.h> /* for getopt */ | 3 | #include <stdlib.h> /* for getopt */ |
4 | 4 | ||
@@ -8,7 +8,6 @@ | @@ -8,7 +8,6 @@ | ||
8 | #include "logger.h" | 8 | #include "logger.h" |
9 | #include "cclass.h" | 9 | #include "cclass.h" |
10 | 10 | ||
11 | - | ||
12 | INIT_CLASS(SERVER); | 11 | INIT_CLASS(SERVER); |
13 | 12 | ||
14 | __construct(SERVER) | 13 | __construct(SERVER) |
@@ -20,27 +19,23 @@ __construct(SERVER) | @@ -20,27 +19,23 @@ __construct(SERVER) | ||
20 | port = va_arg(* params, int); | 19 | port = va_arg(* params, int); |
21 | backlog = va_arg(* params, unsigned int); | 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 | sock_listen(this->sock, backlog); | 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 | __destruct(SERVER) | 30 | __destruct(SERVER) |
33 | { | 31 | { |
34 | int i; | 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 | delete(&this->sock); | 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 | #include <string.h> /* for memset and stuff */ | 2 | #include <string.h> /* for memset and stuff */ |
3 | #include <stdlib.h> /* for exit */ | 3 | #include <stdlib.h> /* for exit */ |
4 | #include <errno.h> /* for errno */ | 4 | #include <errno.h> /* for errno */ |
@@ -13,17 +13,14 @@ | @@ -13,17 +13,14 @@ | ||
13 | #define MAX(x,y) ((x) > (y) ? (x) : (y)) | 13 | #define MAX(x,y) ((x) > (y) ? (x) : (y)) |
14 | 14 | ||
15 | static | 15 | static |
16 | -fd_set | 16 | +int |
17 | server_select(SERVER this) { | 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 | * wait for handles to become ready | 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 | switch (errno) { | 24 | switch (errno) { |
28 | default: | 25 | default: |
29 | case EBADF: | 26 | case EBADF: |
@@ -36,56 +33,48 @@ server_select(SERVER this) { | @@ -36,56 +33,48 @@ server_select(SERVER this) { | ||
36 | logger_log(this->logger, LOGGER_CRIT, | 33 | logger_log(this->logger, LOGGER_CRIT, |
37 | "select systemcall failed: [%s] - service terminated", | 34 | "select systemcall failed: [%s] - service terminated", |
38 | strerror(errno)); | 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 | static | 43 | static |
47 | void | 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 | char remoteAddr[16] = ""; | 48 | char remoteAddr[16] = ""; |
53 | SOCK acc; | 49 | SOCK acc; |
54 | 50 | ||
55 | acc = sock_accept(this->sock, remoteAddr); | 51 | acc = sock_accept(this->sock, remoteAddr); |
56 | 52 | ||
57 | if (-1 != acc->handle) { | 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 | } else { | 58 | } else { |
62 | delete(&acc); | 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 | static | 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 | int | 67 | int |
79 | -server_read(SERVER this, fd_set * rfds) | 68 | +server_read(SERVER this) |
80 | { | 69 | { |
81 | unsigned int i; | 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 | memset(buffer, 0, 1024); | 76 | memset(buffer, 0, 1024); |
88 | - switch (_read = read(i, buffer, 1023)) { | 77 | + switch (_read = read((this->fds)[i].fd, buffer, 1023)) { |
89 | case 0: | 78 | case 0: |
90 | /* | 79 | /* |
91 | * normal close: write remaining data | 80 | * normal close: write remaining data |
@@ -101,6 +90,7 @@ server_read(SERVER this, fd_set * rfds) | @@ -101,6 +90,7 @@ server_read(SERVER this, fd_set * rfds) | ||
101 | break; | 90 | break; |
102 | 91 | ||
103 | default: | 92 | default: |
93 | + (this->fds)[i].revents |= POLLIN; | ||
104 | if (NULL != this->read_hook) { | 94 | if (NULL != this->read_hook) { |
105 | this->read_hook(buffer); | 95 | this->read_hook(buffer); |
106 | } | 96 | } |
@@ -116,24 +106,27 @@ void | @@ -116,24 +106,27 @@ void | ||
116 | server_run(SERVER this) | 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 | logger_log(this->logger, LOGGER_INFO, "service started"); | 111 | logger_log(this->logger, LOGGER_INFO, "service started"); |
122 | 112 | ||
123 | while (!doShutdown) /* until error or signal */ | 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 | * handle accept | 124 | * handle accept |
132 | */ | 125 | */ |
133 | - server_handle_accept(this, &rfds); | 126 | + server_handle_accept(this); |
134 | 127 | ||
135 | /* handle reads */ | 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,17 +32,9 @@ sock_accept(SOCK this, char remoteAddr[16]) | ||
32 | logger_log(this->logger, LOGGER_WARNING, | 32 | logger_log(this->logger, LOGGER_WARNING, |
33 | "error acception connection: %s", strerror(errno)); | 33 | "error acception connection: %s", strerror(errno)); |
34 | } else { | 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 | logger_log(this->logger, LOGGER_INFO, | 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 | return sock; | 39 | return sock; |
48 | } | 40 | } |
@@ -4,18 +4,24 @@ TESTS_ENVIRONMENT = valgrind --error-exitcode=123 --leak-check=full --quiet | @@ -4,18 +4,24 @@ TESTS_ENVIRONMENT = valgrind --error-exitcode=123 --leak-check=full --quiet | ||
4 | TESTS = cclassTest loggerTest socketTest serverTest | 4 | TESTS = cclassTest loggerTest socketTest serverTest |
5 | check_PROGRAMS = cclassTest loggerTest socketTest serverTest | 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 | cclassTest_CFLAGS = -Wall -ggdb -O0 -finline-functions -I ../include -I .. -I . | 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 | loggerTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . | 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 | socketTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . | 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 | serverTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . | 25 | serverTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . |
20 | 26 | ||
21 | EXTRA_DIST = runtest.h mock/class.h | 27 | EXTRA_DIST = runtest.h mock/class.h |
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | +#include <unistd.h> | ||
4 | +#include <signal.h> | ||
3 | 5 | ||
4 | #include "runtest.h" | 6 | #include "runtest.h" |
5 | #include "logger.h" | 7 | #include "logger.h" |
6 | #include "cclass.h" | 8 | #include "cclass.h" |
7 | #include "server.h" | 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 | static void | 21 | static void |
18 | read_hook(const char * _buffer) | 22 | read_hook(const char * _buffer) |
19 | { | 23 | { |
20 | if (NULL != _buffer) { | 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 | static void | 31 | static void |
27 | logfnct_mock(int _level, const char * _msg) | 32 | logfnct_mock(int _level, const char * _msg) |
28 | { | 33 | { |
29 | level = _level; | 34 | level = _level; |
30 | - msg = malloc(strlen(_msg) + 1); | ||
31 | - strcpy(msg, _msg); | 35 | + strncpy(msg, _msg, 1023); |
32 | } | 36 | } |
33 | 37 | ||
34 | const char testname[] = "serverTest"; | 38 | const char testname[] = "serverTest"; |
@@ -48,7 +52,6 @@ __setUp() | @@ -48,7 +52,6 @@ __setUp() | ||
48 | ASSERT_INSTANCE_OF(LOGGER, server->logger); | 52 | ASSERT_INSTANCE_OF(LOGGER, server->logger); |
49 | ASSERT_INSTANCE_OF(SOCK, server->sock); | 53 | ASSERT_INSTANCE_OF(SOCK, server->sock); |
50 | ASSERT_EQUAL(TEST_PORT, server->sock->port); | 54 | ASSERT_EQUAL(TEST_PORT, server->sock->port); |
51 | - ASSERT_EQUAL(server->max_fd, server->sock->handle); | ||
52 | 55 | ||
53 | server->read_hook = read_hook; | 56 | server->read_hook = read_hook; |
54 | 57 | ||
@@ -62,9 +65,9 @@ __tearDown() | @@ -62,9 +65,9 @@ __tearDown() | ||
62 | { | 65 | { |
63 | level = -1; | 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 | if (NULL != logger) { | 73 | if (NULL != logger) { |
@@ -72,11 +75,6 @@ __tearDown() | @@ -72,11 +75,6 @@ __tearDown() | ||
72 | delete(&logger); | 75 | delete(&logger); |
73 | } | 76 | } |
74 | 77 | ||
75 | - if (NULL != server) { | ||
76 | - ASSERT_OBJECT(server); | ||
77 | - delete(&server); | ||
78 | - } | ||
79 | - | ||
80 | return TEST_OK; | 78 | return TEST_OK; |
81 | } | 79 | } |
82 | int (* const tearDown)() = __tearDown; | 80 | int (* const tearDown)() = __tearDown; |
@@ -85,6 +83,32 @@ static | @@ -85,6 +83,32 @@ static | ||
85 | int | 83 | int |
86 | testDummy() | 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 | return TEST_OK; | 112 | return TEST_OK; |
89 | } | 113 | } |
90 | 114 |
@@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
8 | #include "socket.h" | 8 | #include "socket.h" |
9 | 9 | ||
10 | 10 | ||
11 | -#define TEST_PORT 11212 | 11 | +#define TEST_PORT 11213 |
12 | 12 | ||
13 | 13 | ||
14 | int level = -1; | 14 | int level = -1; |
@@ -98,7 +98,6 @@ testAccept() | @@ -98,7 +98,6 @@ testAccept() | ||
98 | delete(&con); | 98 | delete(&con); |
99 | __tearDown(); | 99 | __tearDown(); |
100 | exit(EXIT_SUCCESS); | 100 | exit(EXIT_SUCCESS); |
101 | - break; | ||
102 | 101 | ||
103 | case -1: | 102 | case -1: |
104 | return TEST_FAILED; | 103 | return TEST_FAILED; |
Please
register
or
login
to post a comment