taskrambler  0.1.8
Web server and task management solution.
worker.c
Go to the documentation of this file.
1 /**
2  * \file
3  *
4  * \author Georg Hopp
5  *
6  * \copyright
7  * Copyright © 2012 Georg Hopp
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #define _GNU_SOURCE
24 
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <search.h>
32 
33 #include "class.h"
34 #include "stream.h"
35 #include "hash.h"
36 #include "queue.h"
37 #include "http/worker.h"
38 #include "http/parser.h"
39 #include "http/writer.h"
40 
41 #include "utils/memory.h"
42 #include "interface/subject.h"
43 #include "interface/observer.h"
44 
45 static
46 int
47 httpWorkerCtor(void * _this, va_list * params)
48 {
49  HttpWorker this = _this;
50  char * id = va_arg(*params, char *);
51  char cbuf_id[100];
52 
53  this->id = memMalloc(strlen(id) + 1);
54  strcpy(this->id, id);
55 
56  this->asset_pool = new(Hash);
57 
58  sprintf(cbuf_id, "%s_%s", "parser", id);
59  this->pbuf = new(Cbuf, cbuf_id, PARSER_MAX_BUF);
60 
61  this->additional_headers = new(Queue);
62 
63  this->parser = new(HttpParser, this->pbuf);
64  this->writer = new(HttpWriter);
65 
66  return 0;
67 }
68 
69 static
70 void
71 httpWorkerDtor(void * _this)
72 {
73  HttpWorker this = _this;
74 
75  MEM_FREE(this->id);
76 
77  delete(this->additional_headers);
78 
79  delete(this->parser);
80  delete(this->writer);
81 
82  if (NULL != this->pbuf) {
83  delete(this->asset_pool);
84  delete(this->pbuf); //!< cloned workers have NULL, so delete won't do anything
85  }
86 }
87 
88 static
89 void
90 httpWorkerClone(void * _this, void * _base)
91 {
92  HttpWorker this = _this;
93  HttpWorker base = _base;
94 
95  this->asset_pool = base->asset_pool;
96  this->application_adapter = base->application_adapter;
97 
98  this->additional_headers = new(Queue);
99 
100  this->parser = new(HttpParser, base->pbuf);
101  /*
102  * I am pretty sure that it is not neccessary to have a
103  * separeate writer for each connection...
104  * Right now I leave it that way.
105  * TODO check this.
106  * OK some facts:
107  * - the stream as well as the worker are associated
108  * to the filehandle within the server.
109  * - the response queue is located within the writer.
110  * (this might be wrong...the response queue should
111  * be part of the worker. That way I could give it
112  * into the writer when writing. That way only one
113  * instance of the writer might be possible...)
114  * NO, the previous statement is wrong...this would
115  * involve much more organization overhead within
116  * the writer...queue change and such...
117  * At the end I think it might be best to leave it as
118  * it is.
119  */
120  this->writer = new(HttpWriter);
121 }
122 
123 ssize_t httpWorkerProcess(void *, Stream);
124 ssize_t httpWorkerWrite(void *, Stream);
125 
126 static
127 void
128 httpWorkerDetach(void * _this, void * adapter)
129 {
130  HttpWorker this = (HttpWorker)_this;
131 
132  if (NULL != this->application_adapter) {
133  delete(this->application_adapter);
134  }
135 }
136 
137 static
138 void
139 httpWorkerAttach(void * _this, void * adapter)
140 {
141  HttpWorker this = (HttpWorker)_this;
142 
143  /*
144  * right now only one adapter is allowed and the last
145  * added will be used....all others will be deleted in
146  * assumption that no other handle does exist anymore
147  * (because it was added as an adapter and thus is good
148  * for nothing else.)
149  */
150  httpWorkerDetach(_this, adapter);
151 
152  this->application_adapter = adapter;
153 }
154 
155 static
156 void
157 httpWorkerNotify(void * _this)
158 {
159  HttpWorker this = (HttpWorker)_this;
160 
161  observerUpdate(this->application_adapter, _this);
162 }
163 
165 INIT_IFACE(StreamReader, httpWorkerProcess);
166 INIT_IFACE(StreamWriter, httpWorkerWrite);
169  HttpWorker,
170  NULL,
171  IFACE(Class),
172  IFACE(StreamReader),
173  IFACE(StreamWriter),
174  IFACE(Subject));
175 
176 // vim: set ts=4 sw=4:
#define MEM_FREE(seg)
Definition: memory.h:28
static void httpWorkerAttach(void *_this, void *adapter)
Definition: worker.c:139
ssize_t httpWorkerProcess(void *, Stream)
static void httpWorkerClone(void *_this, void *_base)
Definition: worker.c:90
static void httpWorkerNotify(void *_this)
Definition: worker.c:157
void * memMalloc(size_t)
Definition: memory.c:783
static void httpWorkerDetach(void *_this, void *adapter)
Definition: worker.c:128
#define IFACE(name)
Definition: interface.h:34
CREATE_CLASS(HttpWorker, NULL, IFACE(Class), IFACE(StreamReader), IFACE(StreamWriter), IFACE(Subject))
static int httpWorkerCtor(void *_this, va_list *params)
Definition: worker.c:47
Hash asset_pool
Definition: pool.c:32
INIT_IFACE(Class, httpWorkerCtor, httpWorkerDtor, httpWorkerClone)
ssize_t httpWorkerWrite(void *, Stream)
#define PARSER_MAX_BUF
Definition: parser.h:35
void observerUpdate(void *, void *)
Definition: observer.c:32
static void httpWorkerDtor(void *_this)
Definition: worker.c:71