/** * \file * * \author Georg Hopp * * \copyright * Copyright © 2014 Georg Hopp * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include "trbase.h" #include "trio.h" #include "http/worker.h" #include "http/parser.h" #include "http/writer.h" static int httpWorkerCtor(void * _this, va_list * params) { HttpWorker this = _this; char * id = va_arg(*params, char *); char cbuf_id[100]; this->id = TR_malloc(strlen(id) + 1); strcpy(this->id, id); this->asset_pool = TR_new(TR_Hash); sprintf(cbuf_id, "%s_%s", "parser", id); this->pbuf = TR_new(TR_Cbuf, cbuf_id, PARSER_MAX_BUF); this->additional_headers = TR_new(TR_Queue); this->parser = TR_new(HttpParser, this->pbuf); this->writer = TR_new(HttpWriter); return 0; } static void httpWorkerDtor(void * _this) { HttpWorker this = _this; TR_MEM_FREE(this->id); TR_delete(this->additional_headers); TR_delete(this->parser); TR_delete(this->writer); if (NULL != this->pbuf) { TR_delete(this->asset_pool); TR_delete(this->pbuf); //!< cloned workers have NULL, so delete won't do anything } } static void httpWorkerClone(void * _this, void * _base) { HttpWorker this = _this; HttpWorker base = _base; this->asset_pool = base->asset_pool; this->application_adapter = base->application_adapter; this->additional_headers = TR_new(TR_Queue); this->parser = TR_new(HttpParser, base->pbuf); /* * I am pretty sure that it is not neccessary to have a * separeate writer for each connection... * Right now I leave it that way. * TODO check this. * OK some facts: * - the stream as well as the worker are associated * to the filehandle within the server. * - the response queue is located within the writer. * (this might be wrong...the response queue should * be part of the worker. That way I could give it * into the writer when writing. That way only one * instance of the writer might be possible...) * NO, the previous statement is wrong...this would * involve much more organization overhead within * the writer...queue change and such... * At the end I think it might be best to leave it as * it is. */ this->writer = TR_new(HttpWriter); } ssize_t httpWorkerProcess(void *, TR_Stream); ssize_t httpWorkerWrite(void *, TR_Stream); static void httpWorkerDetach(void * _this, void * adapter) { HttpWorker this = (HttpWorker)_this; if (NULL != this->application_adapter) { TR_delete(this->application_adapter); } } static void httpWorkerAttach(void * _this, void * adapter) { HttpWorker this = (HttpWorker)_this; /* * right now only one adapter is allowed and the last * added will be used....all others will be deleted in * assumption that no other handle does exist anymore * (because it was added as an adapter and thus is good * for nothing else.) */ httpWorkerDetach(_this, adapter); this->application_adapter = adapter; } static void httpWorkerNotify(void * _this) { HttpWorker this = (HttpWorker)_this; TR_observerUpdate(this->application_adapter, _this); } TR_INIT_IFACE(TR_Class, httpWorkerCtor, httpWorkerDtor, httpWorkerClone); TR_INIT_IFACE(TR_StreamReader, httpWorkerProcess); TR_INIT_IFACE(TR_StreamWriter, httpWorkerWrite); TR_INIT_IFACE( TR_Subject, httpWorkerAttach, httpWorkerDetach, httpWorkerNotify); TR_CREATE_CLASS( HttpWorker, NULL, NULL, TR_IF(TR_Class), TR_IF(TR_StreamReader), TR_IF(TR_StreamWriter), TR_IF(TR_Subject)); // vim: set ts=4 sw=4: