diff --git a/include/application/application.h b/include/application/application.h index 59d8fa9..4788c83 100644 --- a/include/application/application.h +++ b/include/application/application.h @@ -24,10 +24,11 @@ #define __APPLICATION_H__ #include + #include "class.h" #include "session.h" -#include "queue.h" +#include "hash.h" #include "auth/credential.h" #include "storage/storage.h" #include "session.h" @@ -40,9 +41,8 @@ struct randval { }; CLASS(Application) { - // should be a list and not a queue but currently queue is - // the closest I have. - Queue active_sessions; + Hash * active_sessions; + time_t session_time_ofs; void ** auth; size_t nauth; @@ -61,6 +61,7 @@ int applicationSignup(Application, Credential, User, Session); Session applicationSessionStart(Application); Session applicationSessionGet(Application, const char *); void applicationSessionStop(Application, Session); +void applicationSessionCleanup(Application, time_t); #endif // __HTTP_HEADER_H__ diff --git a/include/hash/hash.h b/include/hash/hash.h index dd69291..1ba1550 100644 --- a/include/hash/hash.h +++ b/include/hash/hash.h @@ -28,6 +28,7 @@ #include "class.h" #include "tree.h" +#define HASH_IS_EMPTY(h) ((h)->root) CLASS(Hash) { Tree root; @@ -36,9 +37,11 @@ CLASS(Hash) { void * hashAdd(Hash, void *); void * hashDelete(Hash, const char *, size_t); void * hashGet(Hash, const char *, size_t); +void * hashGetFirst(Hash); void * hashDeleteByVal(Hash, unsigned long); void * hashGetByVal(Hash, unsigned long); void hashEach(Hash, void (*)(const void*)); +void hashCleanup(Hash); #endif // __HASH_HASH_H__ diff --git a/src/application/Makefile.am b/src/application/Makefile.am index eb3dbb8..1c01321 100644 --- a/src/application/Makefile.am +++ b/src/application/Makefile.am @@ -7,7 +7,8 @@ APPLICATION = application.c \ signup.c \ session_start.c \ session_stop.c \ - session_get.c + session_get.c \ + session_cleanup.c ADAPTERHTTP = adapter/http/http.c \ adapter/http/update.c diff --git a/src/application/adapter/http/update.c b/src/application/adapter/http/update.c index b0ff15f..d114159 100644 --- a/src/application/adapter/http/update.c +++ b/src/application/adapter/http/update.c @@ -172,16 +172,20 @@ signupAdapter(Application application, HttpWorker worker, Session session) void applicationAdapterHttpUpdate(void * _this, void * subject) { - ApplicationAdapterHttp this = _this; - HttpWorker worker = (HttpWorker)subject; - char * sid; - Session session; - char buf[200]; - size_t nbuf; + ApplicationAdapterHttp this = _this; + HttpWorker worker = (HttpWorker)subject; + Session session = NULL; + time_t now = time(NULL); - sid = getSessionId(worker->current_request->cookies); + char * sid; + char buf[1000]; + size_t nbuf; + applicationSessionCleanup(this->application, now); + + sid = getSessionId(worker->current_request->cookies); session = applicationSessionGet(this->application, sid); + if (NULL == session) { session = applicationSessionStart(this->application); } diff --git a/src/application/application.c b/src/application/application.c index 2c3f45e..9f8e476 100644 --- a/src/application/application.c +++ b/src/application/application.c @@ -25,7 +25,7 @@ #include #include "class.h" -#include "queue.h" +#include "hash.h" #include "application/application.h" #include "storage/storage.h" @@ -58,8 +58,12 @@ applicationCtor(void * _this, va_list * params) this->auth[i] = va_arg(*params, void *); } - this->active_sessions = new(Queue); - this->version = VERSION; + this->active_sessions = memCalloc(SESSION_LIVETIME, sizeof(Hash)); + for (i=0; iactive_sessions[i] = new(Hash); + } + + this->version = VERSION; return 0; } @@ -69,9 +73,13 @@ void applicationDtor(void * _this) { Application this = _this; + size_t i; - delete(this->active_sessions); + for (i=0; iactive_sessions[i]); + } + MEM_FREE(this->active_sessions); MEM_FREE(this->auth); } diff --git a/src/application/session_cleanup.c b/src/application/session_cleanup.c new file mode 100644 index 0000000..09fd23b --- /dev/null +++ b/src/application/session_cleanup.c @@ -0,0 +1,69 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2012 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 "class.h" +#include "session.h" +#include "hash.h" +#include "application/application.h" + +#include "utils/memory.h" + +void +applicationSessionCleanup(Application this, time_t now) +{ + unsigned int expired = now - this->session_time_ofs; + unsigned int i = 0; + + if (SESSION_LIVETIME <= expired) { + expired = SESSION_LIVETIME; + } + + if (0 < expired && SESSION_LIVETIME > expired) { + Hash * tmp_buf = memCalloc(SESSION_LIVETIME, sizeof(Hash)); + unsigned int i = 0; + + memcpy( + &(tmp_buf[expired]), + this->active_sessions, + (SESSION_LIVETIME - expired) * sizeof(Hash)); + memcpy( + tmp_buf, + &(this->active_sessions[SESSION_LIVETIME - expired]), + expired * sizeof(Hash)); + + MEM_FREE(this->active_sessions); + this->active_sessions = tmp_buf; + } + + for (i=0; iactive_sessions[i]); + } + + this->session_time_ofs = now; +} + +// vim: set ts=4 sw=4: diff --git a/src/application/session_get.c b/src/application/session_get.c index 2371b27..d15e04c 100644 --- a/src/application/session_get.c +++ b/src/application/session_get.c @@ -35,40 +35,28 @@ Session applicationSessionGet(Application this, const char * sid) { - Session sess = NULL; - Queue current = this->active_sessions; - time_t now = time(NULL); + Session sess = NULL; + int index; - while (NULL != current->next) { - Session session = (Session)current->next->msg; - - if (now >= session->livetime) { - Queue to_delete = current->next; - - if (to_delete == this->active_sessions->first) { - this->active_sessions->first = to_delete->next; - } - if (to_delete == this->active_sessions->last) { - if (to_delete == this->active_sessions->next) { - this->active_sessions->last = NULL; - } else { - this->active_sessions->last = current; - } + if (NULL != sid) { + /** + * now get the session if not expired + */ + for (index=0; indexactive_sessions)[index], sid, 36); + if (NULL != sess) { + break; } - - current->next = to_delete->next; - - delete(session); - delete(to_delete); - continue; } - if (NULL != sid && 0 == memcmp(session->id, sid, 36)) { - session->livetime = time(NULL) + SESSION_LIVETIME; - sess = session; + /** + * update livetime of session if found + */ + if (NULL != sess) { + sess->livetime = this->session_time_ofs + SESSION_LIVETIME; + hashAdd((this->active_sessions)[0], sess); } - - current = current->next; } return sess; diff --git a/src/application/session_start.c b/src/application/session_start.c index ec28ff1..fcbeed2 100644 --- a/src/application/session_start.c +++ b/src/application/session_start.c @@ -22,24 +22,24 @@ #define _GNU_SOURCE +#include #include #include "class.h" #include "session.h" -#include "queue.h" +#include "hash.h" #include "application/application.h" #include "utils/memory.h" - Session applicationSessionStart(Application this) { - Session session = new(Session); + Session sess = new(Session); - queuePut(this->active_sessions, session); + hashAdd((this->active_sessions)[0], sess); - return session; + return sess; } // vim: set ts=4 sw=4: diff --git a/src/application/session_stop.c b/src/application/session_stop.c index 09d8b32..33a3152 100644 --- a/src/application/session_stop.c +++ b/src/application/session_stop.c @@ -34,7 +34,12 @@ void applicationSessionStop(Application this, Session session) { - session->livetime = 0; + int index = SESSION_LIVETIME - + (session->livetime - this->session_time_ofs); + + if (SESSION_LIVETIME > index) { + hashDeleteByVal((this->active_sessions)[index], session->hash); + } } // vim: set ts=4 sw=4: diff --git a/src/application/signup.c b/src/application/signup.c index 53aff02..0784e8d 100644 --- a/src/application/signup.c +++ b/src/application/signup.c @@ -32,6 +32,7 @@ #include "application/application.h" #include "utils/memory.h" +#include "commons.h" int applicationSignup( diff --git a/src/hash/Makefile.am b/src/hash/Makefile.am index 5727bba..914273e 100644 --- a/src/hash/Makefile.am +++ b/src/hash/Makefile.am @@ -1,8 +1,8 @@ ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = subdir-objects -HASH = hash.c add.c get.c delete.c each.c value.c \ - interface/hashable.c +HASH = hash.c add.c get.c get_first.c delete.c each.c value.c \ + cleanup.c interface/hashable.c noinst_LIBRARIES = libhash.a diff --git a/src/hash/cleanup.c b/src/hash/cleanup.c new file mode 100644 index 0000000..4c2544a --- /dev/null +++ b/src/hash/cleanup.c @@ -0,0 +1,40 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2012 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 . + */ + +#include "hash/hash.h" +#include "class.h" + +static +inline +void +tDelete(const void * node, const int depth) +{ + delete(node); +} + +void +hashCleanup(Hash this) +{ + treeDestroy(&(this->root), tDelete); +} + +// vim: set ts=4 sw=4: diff --git a/src/application/session_update.c b/src/hash/get_first.c similarity index 60% rename from src/application/session_update.c rename to src/hash/get_first.c index 7e8a8bf..66f4bdc 100644 --- a/src/application/session_update.c +++ b/src/hash/get_first.c @@ -20,35 +20,19 @@ * along with this program. If not, see . */ -#define _GNU_SOURCE +#include -#include +#include #include -#include "class.h" -#include "session.h" #include "hash.h" -#include "application/application.h" +#include "tree.h" +#include "utils/hash.h" -#include "utils/memory.h" - - -void -applicationSessionUpdate( - Application this, - const char * sid, - const char * name, - size_t nname) +void * +hashGetFirst(Hash this) { -// Session session = hashGet(this->active_sessions, sid, 36); -// -// if (NULL != session) { -// MEM_FREE(session->username); -// -// session->username = memMalloc(nname + 1); -// session->username[nname] = 0; -// memcpy(session->username, name, nname); -// } + return this->root; } // vim: set ts=4 sw=4: diff --git a/src/hash/hash.c b/src/hash/hash.c index da4cf20..1e4432d 100644 --- a/src/hash/hash.c +++ b/src/hash/hash.c @@ -49,7 +49,7 @@ hashDtor(void * _this) { Hash this = _this; - treeDestroy(&this->root, tDelete); + hashCleanup(this); } INIT_IFACE(Class, hashCtor, hashDtor, NULL);