Browse Source

optimized session handling. closes #41

release0.1.6
Georg Hopp 12 years ago
parent
commit
1dd874a99b
  1. 9
      include/application/application.h
  2. 3
      include/hash/hash.h
  3. 3
      src/application/Makefile.am
  4. 10
      src/application/adapter/http/update.c
  5. 14
      src/application/application.c
  6. 69
      src/application/session_cleanup.c
  7. 44
      src/application/session_get.c
  8. 10
      src/application/session_start.c
  9. 7
      src/application/session_stop.c
  10. 1
      src/application/signup.c
  11. 4
      src/hash/Makefile.am
  12. 40
      src/hash/cleanup.c
  13. 30
      src/hash/get_first.c
  14. 2
      src/hash/hash.c

9
include/application/application.h

@ -24,10 +24,11 @@
#define __APPLICATION_H__
#include <sys/types.h>
#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__

3
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__

3
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

10
src/application/adapter/http/update.c

@ -174,14 +174,18 @@ applicationAdapterHttpUpdate(void * _this, void * subject)
{
ApplicationAdapterHttp this = _this;
HttpWorker worker = (HttpWorker)subject;
Session session = NULL;
time_t now = time(NULL);
char * sid;
Session session;
char buf[200];
char buf[1000];
size_t nbuf;
sid = getSessionId(worker->current_request->cookies);
applicationSessionCleanup(this->application, now);
sid = getSessionId(worker->current_request->cookies);
session = applicationSessionGet(this->application, sid);
if (NULL == session) {
session = applicationSessionStart(this->application);
}

14
src/application/application.c

@ -25,7 +25,7 @@
#include <stdarg.h>
#include "class.h"
#include "queue.h"
#include "hash.h"
#include "application/application.h"
#include "storage/storage.h"
@ -58,7 +58,11 @@ applicationCtor(void * _this, va_list * params)
this->auth[i] = va_arg(*params, void *);
}
this->active_sessions = new(Queue);
this->active_sessions = memCalloc(SESSION_LIVETIME, sizeof(Hash));
for (i=0; i<SESSION_LIVETIME; i++) {
this->active_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; i<SESSION_LIVETIME; i++) {
delete(this->active_sessions[i]);
}
MEM_FREE(this->active_sessions);
MEM_FREE(this->auth);
}

69
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 <http://www.gnu.org/licenses/>.
*/
#define _GNU_SOURCE
#include <stdlib.h>
#include <sys/types.h>
#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; i<expired; i++) {
hashCleanup(this->active_sessions[i]);
}
this->session_time_ofs = now;
}
// vim: set ts=4 sw=4:

44
src/application/session_get.c

@ -36,39 +36,27 @@ Session
applicationSessionGet(Application this, const char * sid)
{
Session sess = NULL;
Queue current = this->active_sessions;
time_t now = time(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; index<SESSION_LIVETIME; index++) {
sess = (Session)hashDelete(
(this->active_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;

10
src/application/session_start.c

@ -22,24 +22,24 @@
#define _GNU_SOURCE
#include <stdlib.h>
#include <sys/types.h>
#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:

7
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:

1
src/application/signup.c

@ -32,6 +32,7 @@
#include "application/application.h"
#include "utils/memory.h"
#include "commons.h"
int
applicationSignup(

4
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

40
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 <http://www.gnu.org/licenses/>.
*/
#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:

30
src/application/session_update.c → src/hash/get_first.c

@ -20,35 +20,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <search.h>
#include <sys/types.h>
#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:

2
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);

Loading…
Cancel
Save