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,9 +4,9 @@ | ||
| 4 | # Project related configuration options | 4 | # Project related configuration options |
| 5 | #--------------------------------------------------------------------------- | 5 | #--------------------------------------------------------------------------- |
| 6 | DOXYFILE_ENCODING = UTF-8 | 6 | DOXYFILE_ENCODING = UTF-8 |
| 7 | -PROJECT_NAME = server | 7 | +PROJECT_NAME = Server |
| 8 | PROJECT_NUMBER = 0.0.1 | 8 | PROJECT_NUMBER = 0.0.1 |
| 9 | -PROJECT_BRIEF = basic server infrastructure | 9 | +PROJECT_BRIEF = "HTTP/REST server implementation" |
| 10 | PROJECT_LOGO = | 10 | PROJECT_LOGO = |
| 11 | OUTPUT_DIRECTORY = docs | 11 | OUTPUT_DIRECTORY = docs |
| 12 | CREATE_SUBDIRS = NO | 12 | CREATE_SUBDIRS = NO |
| @@ -27,7 +27,7 @@ INHERIT_DOCS = YES | @@ -27,7 +27,7 @@ INHERIT_DOCS = YES | ||
| 27 | SEPARATE_MEMBER_PAGES = NO | 27 | SEPARATE_MEMBER_PAGES = NO |
| 28 | TAB_SIZE = 8 | 28 | TAB_SIZE = 8 |
| 29 | ALIASES = | 29 | ALIASES = |
| 30 | -OPTIMIZE_OUTPUT_FOR_C = NO | 30 | +OPTIMIZE_OUTPUT_FOR_C = YES |
| 31 | OPTIMIZE_OUTPUT_JAVA = NO | 31 | OPTIMIZE_OUTPUT_JAVA = NO |
| 32 | OPTIMIZE_FOR_FORTRAN = NO | 32 | OPTIMIZE_FOR_FORTRAN = NO |
| 33 | OPTIMIZE_OUTPUT_VHDL = NO | 33 | OPTIMIZE_OUTPUT_VHDL = NO |
| @@ -40,7 +40,7 @@ CLASS(HttpResponse) { | @@ -40,7 +40,7 @@ CLASS(HttpResponse) { | ||
| 40 | 40 | ||
| 41 | HttpResponse httpResponse304(int, const char *); | 41 | HttpResponse httpResponse304(int, const char *); |
| 42 | HttpResponse httpResponse404(); | 42 | HttpResponse httpResponse404(); |
| 43 | -HttpResponse httpResponseMe(); | 43 | +HttpResponse httpResponseMe(int); |
| 44 | HttpResponse httpResponseImage(int); | 44 | HttpResponse httpResponseImage(int); |
| 45 | 45 | ||
| 46 | #endif // __HTTP_RESPONSE_H__ | 46 | #endif // __HTTP_RESPONSE_H__ |
| @@ -37,12 +37,12 @@ | @@ -37,12 +37,12 @@ | ||
| 37 | " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" \ | 37 | " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" \ |
| 38 | "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" \ | 38 | "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" \ |
| 39 | "<head><title>200 - OK</title></head>" \ | 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 | "</html>" | 41 | "</html>" |
| 42 | 42 | ||
| 43 | 43 | ||
| 44 | HttpResponse | 44 | HttpResponse |
| 45 | -httpResponseMe() | 45 | +httpResponseMe(int value) |
| 46 | { | 46 | { |
| 47 | char buffer[200]; | 47 | char buffer[200]; |
| 48 | HttpResponse response; | 48 | HttpResponse response; |
| @@ -58,8 +58,8 @@ httpResponseMe() | @@ -58,8 +58,8 @@ httpResponseMe() | ||
| 58 | 58 | ||
| 59 | message->type = HTTP_MESSAGE_BUFFERED; | 59 | message->type = HTTP_MESSAGE_BUFFERED; |
| 60 | message->nbody = sizeof(RESP_DATA) - 1; | 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 | sprintf(buffer, "%d", message->nbody); | 64 | sprintf(buffer, "%d", message->nbody); |
| 65 | httpHeaderAdd(&(message->header), | 65 | httpHeaderAdd(&(message->header), |
| @@ -20,10 +20,12 @@ ctor(void * _this, va_list * params) | @@ -20,10 +20,12 @@ ctor(void * _this, va_list * params) | ||
| 20 | { | 20 | { |
| 21 | HttpWorker this = _this; | 21 | HttpWorker this = _this; |
| 22 | char * id = va_arg(*params, char *); | 22 | char * id = va_arg(*params, char *); |
| 23 | + int * val = va_arg(*params, int *); | ||
| 23 | char cbuf_id[100]; | 24 | char cbuf_id[100]; |
| 24 | 25 | ||
| 25 | - this->id = malloc(strlen(id) + 1); | 26 | + this->id = malloc(strlen(id) + 1); |
| 26 | strcpy(this->id, id); | 27 | strcpy(this->id, id); |
| 28 | + this->val = val; | ||
| 27 | 29 | ||
| 28 | sprintf(cbuf_id, "%s_%s", "parser", id); | 30 | sprintf(cbuf_id, "%s_%s", "parser", id); |
| 29 | this->pbuf = new(Cbuf, cbuf_id, REQUEST_PARSER_BUFFER_MAX); | 31 | this->pbuf = new(Cbuf, cbuf_id, REQUEST_PARSER_BUFFER_MAX); |
| @@ -58,6 +60,7 @@ _clone(void * _this, void * _base) | @@ -58,6 +60,7 @@ _clone(void * _this, void * _base) | ||
| 58 | HttpWorker base = _base; | 60 | HttpWorker base = _base; |
| 59 | 61 | ||
| 60 | this->id = NULL; | 62 | this->id = NULL; |
| 63 | + this->val = base->val; | ||
| 61 | this->pbuf = NULL; | 64 | this->pbuf = NULL; |
| 62 | this->wbuf = NULL; | 65 | this->wbuf = NULL; |
| 63 | 66 |
| @@ -56,7 +56,7 @@ httpWorkerProcess(HttpWorker this, int fd) | @@ -56,7 +56,7 @@ httpWorkerProcess(HttpWorker this, int fd) | ||
| 56 | 56 | ||
| 57 | if (0 == strcmp("GET", request->method) && | 57 | if (0 == strcmp("GET", request->method) && |
| 58 | 0 == strcmp("/me/", request->uri)) { | 58 | 0 == strcmp("/me/", request->uri)) { |
| 59 | - response = (HttpMessage)httpResponseMe(); | 59 | + response = (HttpMessage)httpResponseMe(*(this->val)); |
| 60 | } | 60 | } |
| 61 | else if (0 == strcmp("GET", request->method) && | 61 | else if (0 == strcmp("GET", request->method) && |
| 62 | 0 == strcmp("/image/", request->uri)) { | 62 | 0 == strcmp("/image/", request->uri)) { |
| @@ -48,6 +48,14 @@ serverRun(Server this) | @@ -48,6 +48,14 @@ serverRun(Server this) | ||
| 48 | * this single process. | 48 | * this single process. |
| 49 | * What we can first do to get some processing between read/write | 49 | * What we can first do to get some processing between read/write |
| 50 | * cicles is to use the poll timeout. | 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 | while (!doShutdown) //! until error or signal | 60 | while (!doShutdown) //! until error or signal |
| 53 | { | 61 | { |
| @@ -20,12 +20,19 @@ | @@ -20,12 +20,19 @@ | ||
| 20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 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 | #include <sys/time.h> | 27 | #include <sys/time.h> |
| 28 | #include <sys/resource.h> | 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 | #include "server.h" | 37 | #include "server.h" |
| 31 | #include "logger.h" | 38 | #include "logger.h" |
| @@ -35,25 +42,126 @@ | @@ -35,25 +42,126 @@ | ||
| 35 | 42 | ||
| 36 | #include "utils/signalHandling.h" | 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 | void daemonize(void); | 52 | void daemonize(void); |
| 39 | 53 | ||
| 40 | int | 54 | int |
| 41 | main() | 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 | struct rlimit limit = {RLIM_INFINITY, RLIM_INFINITY}; | 63 | struct rlimit limit = {RLIM_INFINITY, RLIM_INFINITY}; |
| 48 | setrlimit(RLIMIT_CPU, &limit); | 64 | setrlimit(RLIMIT_CPU, &limit); |
| 49 | 65 | ||
| 50 | init_signals(); | 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 | return 0; | 166 | return 0; |
| 59 | } | 167 | } |
Please
register
or
login
to post a comment