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