Commit 01ae8736e96acc7ea120b0653bef21ae84e449ec
1 parent
7f688412
now a child is spawned and writes random values in a shared memory segment. Thes…
…e values will be shown in the me action
Showing
8 changed files
with
141 additions
and
21 deletions
... | ... | @@ -4,9 +4,9 @@ |
4 | 4 | # Project related configuration options |
5 | 5 | #--------------------------------------------------------------------------- |
6 | 6 | DOXYFILE_ENCODING = UTF-8 |
7 | -PROJECT_NAME = server | |
7 | +PROJECT_NAME = Server | |
8 | 8 | PROJECT_NUMBER = 0.0.1 |
9 | -PROJECT_BRIEF = basic server infrastructure | |
9 | +PROJECT_BRIEF = "HTTP/REST server implementation" | |
10 | 10 | PROJECT_LOGO = |
11 | 11 | OUTPUT_DIRECTORY = docs |
12 | 12 | CREATE_SUBDIRS = NO |
... | ... | @@ -27,7 +27,7 @@ INHERIT_DOCS = YES |
27 | 27 | SEPARATE_MEMBER_PAGES = NO |
28 | 28 | TAB_SIZE = 8 |
29 | 29 | ALIASES = |
30 | -OPTIMIZE_OUTPUT_FOR_C = NO | |
30 | +OPTIMIZE_OUTPUT_FOR_C = YES | |
31 | 31 | OPTIMIZE_OUTPUT_JAVA = NO |
32 | 32 | OPTIMIZE_FOR_FORTRAN = NO |
33 | 33 | OPTIMIZE_OUTPUT_VHDL = NO | ... | ... |
... | ... | @@ -40,7 +40,7 @@ CLASS(HttpResponse) { |
40 | 40 | |
41 | 41 | HttpResponse httpResponse304(int, const char *); |
42 | 42 | HttpResponse httpResponse404(); |
43 | -HttpResponse httpResponseMe(); | |
43 | +HttpResponse httpResponseMe(int); | |
44 | 44 | HttpResponse httpResponseImage(int); |
45 | 45 | |
46 | 46 | #endif // __HTTP_RESPONSE_H__ | ... | ... |
... | ... | @@ -37,12 +37,12 @@ |
37 | 37 | " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" \ |
38 | 38 | "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" \ |
39 | 39 | "<head><title>200 - OK</title></head>" \ |
40 | - "<body><h1>200 - OK</h1><img src=\"/image/\" /></body>" \ | |
40 | + "<body><h1>200 - OK</h1><img src=\"/image/\" /><hr />%02d</body>" \ | |
41 | 41 | "</html>" |
42 | 42 | |
43 | 43 | |
44 | 44 | HttpResponse |
45 | -httpResponseMe() | |
45 | +httpResponseMe(int value) | |
46 | 46 | { |
47 | 47 | char buffer[200]; |
48 | 48 | HttpResponse response; |
... | ... | @@ -58,8 +58,8 @@ httpResponseMe() |
58 | 58 | |
59 | 59 | message->type = HTTP_MESSAGE_BUFFERED; |
60 | 60 | message->nbody = sizeof(RESP_DATA) - 1; |
61 | - message->body = calloc(1, sizeof(RESP_DATA)); | |
62 | - strcpy(message->body, RESP_DATA); | |
61 | + message->body = calloc(1, sizeof(RESP_DATA)-2); | |
62 | + sprintf(message->body, RESP_DATA, value); | |
63 | 63 | |
64 | 64 | sprintf(buffer, "%d", message->nbody); |
65 | 65 | httpHeaderAdd(&(message->header), | ... | ... |
... | ... | @@ -20,10 +20,12 @@ ctor(void * _this, va_list * params) |
20 | 20 | { |
21 | 21 | HttpWorker this = _this; |
22 | 22 | char * id = va_arg(*params, char *); |
23 | + int * val = va_arg(*params, int *); | |
23 | 24 | char cbuf_id[100]; |
24 | 25 | |
25 | - this->id = malloc(strlen(id) + 1); | |
26 | + this->id = malloc(strlen(id) + 1); | |
26 | 27 | strcpy(this->id, id); |
28 | + this->val = val; | |
27 | 29 | |
28 | 30 | sprintf(cbuf_id, "%s_%s", "parser", id); |
29 | 31 | this->pbuf = new(Cbuf, cbuf_id, REQUEST_PARSER_BUFFER_MAX); |
... | ... | @@ -58,6 +60,7 @@ _clone(void * _this, void * _base) |
58 | 60 | HttpWorker base = _base; |
59 | 61 | |
60 | 62 | this->id = NULL; |
63 | + this->val = base->val; | |
61 | 64 | this->pbuf = NULL; |
62 | 65 | this->wbuf = NULL; |
63 | 66 | ... | ... |
... | ... | @@ -56,7 +56,7 @@ httpWorkerProcess(HttpWorker this, int fd) |
56 | 56 | |
57 | 57 | if (0 == strcmp("GET", request->method) && |
58 | 58 | 0 == strcmp("/me/", request->uri)) { |
59 | - response = (HttpMessage)httpResponseMe(); | |
59 | + response = (HttpMessage)httpResponseMe(*(this->val)); | |
60 | 60 | } |
61 | 61 | else if (0 == strcmp("GET", request->method) && |
62 | 62 | 0 == strcmp("/image/", request->uri)) { | ... | ... |
... | ... | @@ -48,6 +48,14 @@ serverRun(Server this) |
48 | 48 | * this single process. |
49 | 49 | * What we can first do to get some processing between read/write |
50 | 50 | * cicles is to use the poll timeout. |
51 | + * A first candidate for a separate process would be the | |
52 | + * generation of the responses piped responses then still need | |
53 | + * to open the filehandle in this process and reading and | |
54 | + * writing would be done here. So the benefit might not be | |
55 | + * very big. Otherwise we could share the read and write | |
56 | + * ringbuffer as well as the message queues. Then the child | |
57 | + * process can do the file readings, but this would involve | |
58 | + * some more IPC. | |
51 | 59 | */ |
52 | 60 | while (!doShutdown) //! until error or signal |
53 | 61 | { | ... | ... |
... | ... | @@ -20,12 +20,19 @@ |
20 | 20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
21 | 21 | */ |
22 | 22 | |
23 | -#include <stdio.h> | |
24 | -#include <socket.h> | |
25 | -#include <string.h> | |
23 | +#include <unistd.h> | |
24 | +#include <stdlib.h> | |
25 | +#include <fcntl.h> | |
26 | 26 | |
27 | 27 | #include <sys/time.h> |
28 | 28 | #include <sys/resource.h> |
29 | +#include <sys/types.h> | |
30 | +#include <sys/wait.h> | |
31 | +#include <sys/time.h> | |
32 | +#include <sys/signal.h> | |
33 | +#include <sys/param.h> | |
34 | +#include <sys/stat.h> | |
35 | +#include <sys/mman.h> | |
29 | 36 | |
30 | 37 | #include "server.h" |
31 | 38 | #include "logger.h" |
... | ... | @@ -35,25 +42,126 @@ |
35 | 42 | |
36 | 43 | #include "utils/signalHandling.h" |
37 | 44 | |
45 | +//#define DEFAULT_SECS 0 | |
46 | +//#define DEFAULT_USECS (1000000 / HZ) | |
47 | +#define DEFAULT_SECS 1 | |
48 | +#define DEFAULT_USECS 0 | |
49 | + | |
50 | +void nullhandler() {} | |
51 | + | |
38 | 52 | void daemonize(void); |
39 | 53 | |
40 | 54 | int |
41 | 55 | main() |
42 | 56 | { |
43 | - Logger logger = new(LoggerSyslog, LOGGER_ERR); | |
44 | - HttpWorker worker = new(HttpWorker, "my"); | |
45 | - Server server = new(Server, logger, worker, 11212, SOMAXCONN); | |
57 | + pid_t pid; | |
58 | + long psize = sysconf(_SC_PAGESIZE); | |
59 | + int status; | |
60 | + int shm; | |
61 | + int * value; | |
46 | 62 | |
47 | 63 | struct rlimit limit = {RLIM_INFINITY, RLIM_INFINITY}; |
48 | 64 | setrlimit(RLIMIT_CPU, &limit); |
49 | 65 | |
50 | 66 | init_signals(); |
51 | - //daemonize(); | |
52 | - serverRun(server); | |
53 | 67 | |
54 | - delete(&server); | |
55 | - delete(&worker); | |
56 | - delete(&logger); | |
68 | + shm = shm_open("/fooshm", O_RDWR|O_CREAT, S_IRWXU); | |
69 | + ftruncate(shm, psize); | |
70 | + | |
71 | + switch((pid = fork())) { | |
72 | + case -1: | |
73 | + break; | |
74 | + | |
75 | + case 0: | |
76 | + { | |
77 | + sigset_t block_these, pause_mask; | |
78 | + struct sigaction s; | |
79 | + struct itimerval interval; | |
80 | + | |
81 | + value = mmap (0, sizeof(int), PROT_READ|PROT_WRITE, | |
82 | + MAP_SHARED, shm, 0); | |
83 | + *value = 0; | |
84 | + | |
85 | + close(shm); | |
86 | + | |
87 | + /* Block SIGALRM */ | |
88 | + sigemptyset(&block_these); | |
89 | + sigaddset(&block_these, SIGALRM); | |
90 | + sigprocmask(SIG_BLOCK, &block_these, &pause_mask); | |
91 | + | |
92 | + /* Set up handler for SIGALRM */ | |
93 | + sigemptyset(&s.sa_mask); | |
94 | + sigaddset(&s.sa_mask, SIGINT); | |
95 | + s.sa_flags = 0; | |
96 | + s.sa_handler = nullhandler; | |
97 | + if (sigaction(SIGALRM, &s, NULL) < 0) { | |
98 | + perror("sigaction SIGALRM"); | |
99 | + exit (1); | |
100 | + } | |
101 | + | |
102 | + interval.it_value.tv_sec = DEFAULT_SECS; | |
103 | + interval.it_value.tv_usec = DEFAULT_USECS; | |
104 | + interval.it_interval.tv_sec = DEFAULT_SECS; | |
105 | + interval.it_interval.tv_usec = DEFAULT_USECS; | |
106 | + | |
107 | + setitimer(ITIMER_REAL, &interval, NULL); | |
108 | + | |
109 | + // child | |
110 | + while(!doShutdown) { | |
111 | + *value = rand() % 10; | |
112 | + sigsuspend(&pause_mask); | |
113 | + } | |
114 | + | |
115 | + _exit(EXIT_SUCCESS); | |
116 | + } | |
117 | + | |
118 | + default: | |
119 | + { | |
120 | + Logger logger; | |
121 | + HttpWorker worker; | |
122 | + Server server; | |
123 | + | |
124 | + value = mmap (0, sizeof(int), PROT_READ|PROT_WRITE, | |
125 | + MAP_SHARED, shm, 0); | |
126 | + | |
127 | + shm_unlink("/fooshm"); | |
128 | + close(shm); | |
129 | + | |
130 | + logger = new(LoggerSyslog, LOGGER_ERR); | |
131 | + worker = new(HttpWorker, "my", value); | |
132 | + server = new(Server, logger, worker, 11212, SOMAXCONN); | |
133 | + | |
134 | + //daemonize(); | |
135 | + serverRun(server); | |
136 | + | |
137 | + do { | |
138 | + pid_t w; | |
139 | + | |
140 | + w = waitpid(pid, &status, WUNTRACED | WCONTINUED); | |
141 | + | |
142 | + if (w == -1) { | |
143 | + perror("waitpid"); | |
144 | + exit(EXIT_FAILURE); | |
145 | + } | |
146 | + | |
147 | + if (WIFEXITED(status)) { | |
148 | + printf("exited, status=%d\n", WEXITSTATUS(status)); | |
149 | + } else if (WIFSIGNALED(status)) { | |
150 | + printf("killed by signal %d\n", WTERMSIG(status)); | |
151 | + } else if (WIFSTOPPED(status)) { | |
152 | + printf("stopped by signal %d\n", WSTOPSIG(status)); | |
153 | + } else if (WIFCONTINUED(status)) { | |
154 | + printf("continued\n"); | |
155 | + } | |
156 | + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); | |
157 | + | |
158 | + delete(&server); | |
159 | + delete(&worker); | |
160 | + delete(&logger); | |
161 | + } | |
162 | + | |
163 | + break; | |
164 | + } | |
57 | 165 | |
58 | 166 | return 0; |
59 | 167 | } | ... | ... |
Please
register
or
login
to post a comment