Browse Source

now a child is spawned and writes random values in a shared memory segment. These values will be shown in the me action

master
Georg Hopp 14 years ago
parent
commit
01ae8736e9
  1. 6
      .doxygen
  2. 2
      include/http/response.h
  3. 1
      include/http/worker.h
  4. 8
      src/http/response/me.c
  5. 3
      src/http/worker.c
  6. 2
      src/http/worker/process.c
  7. 8
      src/server/run.c
  8. 120
      src/testserver.c

6
.doxygen

@ -4,9 +4,9 @@
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = server
PROJECT_NAME = Server
PROJECT_NUMBER = 0.0.1
PROJECT_BRIEF = basic server infrastructure
PROJECT_BRIEF = "HTTP/REST server implementation"
PROJECT_LOGO =
OUTPUT_DIRECTORY = docs
CREATE_SUBDIRS = NO
@ -27,7 +27,7 @@ INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO

2
include/http/response.h

@ -40,7 +40,7 @@ CLASS(HttpResponse) {
HttpResponse httpResponse304(int, const char *);
HttpResponse httpResponse404();
HttpResponse httpResponseMe();
HttpResponse httpResponseMe(int);
HttpResponse httpResponseImage(int);
#endif // __HTTP_RESPONSE_H__

1
include/http/worker.h

@ -44,6 +44,7 @@
CLASS(HttpWorker) {
char * id;
int * val;
Cbuf pbuf;
Cbuf wbuf;

8
src/http/response/me.c

@ -37,12 +37,12 @@
" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" \
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" \
"<head><title>200 - OK</title></head>" \
"<body><h1>200 - OK</h1><img src=\"/image/\" /></body>" \
"<body><h1>200 - OK</h1><img src=\"/image/\" /><hr />%02d</body>" \
"</html>"
HttpResponse
httpResponseMe()
httpResponseMe(int value)
{
char buffer[200];
HttpResponse response;
@ -58,8 +58,8 @@ httpResponseMe()
message->type = HTTP_MESSAGE_BUFFERED;
message->nbody = sizeof(RESP_DATA) - 1;
message->body = calloc(1, sizeof(RESP_DATA));
strcpy(message->body, RESP_DATA);
message->body = calloc(1, sizeof(RESP_DATA)-2);
sprintf(message->body, RESP_DATA, value);
sprintf(buffer, "%d", message->nbody);
httpHeaderAdd(&(message->header),

3
src/http/worker.c

@ -20,10 +20,12 @@ ctor(void * _this, va_list * params)
{
HttpWorker this = _this;
char * id = va_arg(*params, char *);
int * val = va_arg(*params, int *);
char cbuf_id[100];
this->id = malloc(strlen(id) + 1);
strcpy(this->id, id);
this->val = val;
sprintf(cbuf_id, "%s_%s", "parser", id);
this->pbuf = new(Cbuf, cbuf_id, REQUEST_PARSER_BUFFER_MAX);
@ -58,6 +60,7 @@ _clone(void * _this, void * _base)
HttpWorker base = _base;
this->id = NULL;
this->val = base->val;
this->pbuf = NULL;
this->wbuf = NULL;

2
src/http/worker/process.c

@ -56,7 +56,7 @@ httpWorkerProcess(HttpWorker this, int fd)
if (0 == strcmp("GET", request->method) &&
0 == strcmp("/me/", request->uri)) {
response = (HttpMessage)httpResponseMe();
response = (HttpMessage)httpResponseMe(*(this->val));
}
else if (0 == strcmp("GET", request->method) &&
0 == strcmp("/image/", request->uri)) {

8
src/server/run.c

@ -48,6 +48,14 @@ serverRun(Server this)
* this single process.
* What we can first do to get some processing between read/write
* cicles is to use the poll timeout.
* A first candidate for a separate process would be the
* generation of the responses piped responses then still need
* to open the filehandle in this process and reading and
* writing would be done here. So the benefit might not be
* very big. Otherwise we could share the read and write
* ringbuffer as well as the message queues. Then the child
* process can do the file readings, but this would involve
* some more IPC.
*/
while (!doShutdown) //! until error or signal
{

120
src/testserver.c

@ -20,12 +20,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <socket.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include "server.h"
#include "logger.h"
@ -35,25 +42,126 @@
#include "utils/signalHandling.h"
//#define DEFAULT_SECS 0
//#define DEFAULT_USECS (1000000 / HZ)
#define DEFAULT_SECS 1
#define DEFAULT_USECS 0
void nullhandler() {}
void daemonize(void);
int
main()
{
Logger logger = new(LoggerSyslog, LOGGER_ERR);
HttpWorker worker = new(HttpWorker, "my");
Server server = new(Server, logger, worker, 11212, SOMAXCONN);
pid_t pid;
long psize = sysconf(_SC_PAGESIZE);
int status;
int shm;
int * value;
struct rlimit limit = {RLIM_INFINITY, RLIM_INFINITY};
setrlimit(RLIMIT_CPU, &limit);
init_signals();
shm = shm_open("/fooshm", O_RDWR|O_CREAT, S_IRWXU);
ftruncate(shm, psize);
switch((pid = fork())) {
case -1:
break;
case 0:
{
sigset_t block_these, pause_mask;
struct sigaction s;
struct itimerval interval;
value = mmap (0, sizeof(int), PROT_READ|PROT_WRITE,
MAP_SHARED, shm, 0);
*value = 0;
close(shm);
/* Block SIGALRM */
sigemptyset(&block_these);
sigaddset(&block_these, SIGALRM);
sigprocmask(SIG_BLOCK, &block_these, &pause_mask);
/* Set up handler for SIGALRM */
sigemptyset(&s.sa_mask);
sigaddset(&s.sa_mask, SIGINT);
s.sa_flags = 0;
s.sa_handler = nullhandler;
if (sigaction(SIGALRM, &s, NULL) < 0) {
perror("sigaction SIGALRM");
exit (1);
}
interval.it_value.tv_sec = DEFAULT_SECS;
interval.it_value.tv_usec = DEFAULT_USECS;
interval.it_interval.tv_sec = DEFAULT_SECS;
interval.it_interval.tv_usec = DEFAULT_USECS;
setitimer(ITIMER_REAL, &interval, NULL);
// child
while(!doShutdown) {
*value = rand() % 10;
sigsuspend(&pause_mask);
}
_exit(EXIT_SUCCESS);
}
default:
{
Logger logger;
HttpWorker worker;
Server server;
value = mmap (0, sizeof(int), PROT_READ|PROT_WRITE,
MAP_SHARED, shm, 0);
shm_unlink("/fooshm");
close(shm);
logger = new(LoggerSyslog, LOGGER_ERR);
worker = new(HttpWorker, "my", value);
server = new(Server, logger, worker, 11212, SOMAXCONN);
//daemonize();
serverRun(server);
do {
pid_t w;
w = waitpid(pid, &status, WUNTRACED | WCONTINUED);
if (w == -1) {
perror("waitpid");
exit(EXIT_FAILURE);
}
if (WIFEXITED(status)) {
printf("exited, status=%d\n", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
printf("killed by signal %d\n", WTERMSIG(status));
} else if (WIFSTOPPED(status)) {
printf("stopped by signal %d\n", WSTOPSIG(status));
} else if (WIFCONTINUED(status)) {
printf("continued\n");
}
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
delete(&server);
delete(&worker);
delete(&logger);
}
break;
}
return 0;
}

Loading…
Cancel
Save