-/* timeq.c - NeonServ v5.4
+/* timeq.c - NeonServ v5.5
* Copyright (C) 2011-2012 Philipp Kreil (pk910)
*
* This program is free software: you can redistribute it and/or modify
*/
#include "timeq.h"
+#include "IOHandler.h"
static struct timeq_entry *timeq_events;
#ifdef HAVE_THREADS
+static int pthread_mutex_initialized = 0;
static pthread_mutex_t synchronized;
#endif
-void init_timeq() {
- THREAD_MUTEX_INIT(synchronized);
-}
-
-void timeq_tick() {
- SYNCHRONIZE(synchronized);
- struct timeq_entry *entry, *next;
- struct timeval now;
- gettimeofday(&now, NULL);
- for(entry = timeq_events; entry; entry = next) {
- if(!timeval_is_bigger(entry->execute, now)) {
- next = entry->next;
- if(timeq_events == entry)
- timeq_events = next;
- entry->callback(entry->data);
- free(entry);
- } else
- break;
+static IOHANDLER_CALLBACK(timeq_callback) {
+ struct timeq_entry *entry = event->iofd->data;
+ switch(event->type) {
+ case IOEVENT_TIMEOUT:
+ entry->callback(entry->data);
+ entry->iofd = NULL;
+ timeq_del(entry);
+ break;
+ default:
+ break;
}
- DESYNCHRONIZE(synchronized);
}
struct timeq_entry* timeq_add(int seconds, int module_id, timeq_callback_t *callback, void *data) {
}
struct timeq_entry* timeq_uadd(int useconds, int module_id, timeq_callback_t *callback, void *data) {
- struct timeval now;
- gettimeofday(&now, NULL);
+ struct timeval timeout;
struct timeq_entry *entry = malloc(sizeof(*entry));
if (!entry)
{
perror("malloc() failed");
return NULL;
}
+ #ifdef HAVE_THREADS
+ if(!pthread_mutex_initialized) {
+ THREAD_MUTEX_INIT(synchronized);
+ pthread_mutex_initialized = 1;
+ }
+ #endif
+ gettimeofday(&timeout, NULL);
SYNCHRONIZE(synchronized);
- now.tv_usec += (useconds % 1000);
- now.tv_sec += (useconds / 1000);
- entry->execute = now;
+ timeout.tv_usec += (useconds % 1000);
+ timeout.tv_sec += (useconds / 1000);
+ entry->iofd = iohandler_timer(timeout, timeq_callback);
+ entry->iofd->data = entry;
entry->module_id = module_id;
entry->callback = callback;
entry->data = data;
entry->name = NULL;
- struct timeq_entry *next, *prev = NULL;
- for(next = timeq_events; next; next = next->next) {
- if(timeval_is_bigger(next->execute, now))
- break;
- else
- prev = next;
- }
- if(prev == NULL) {
- entry->next = timeq_events;
- timeq_events = entry;
- } else {
- entry->next = next;
- prev->next = entry;
- }
+ entry->next = timeq_events;
+ entry->prev = NULL;
+ if(timeq_events)
+ timeq_events->prev = entry;
+ timeq_events = entry;
DESYNCHRONIZE(synchronized);
return entry;
}
}
struct timeq_entry* timeq_uadd_name(char *name, int useconds, int module_id, timeq_callback_t *callback, void *data) {
- SYNCHRONIZE(synchronized);
struct timeq_entry *entry = timeq_uadd(useconds, module_id, callback, data);
entry->name = strdup(name);
- DESYNCHRONIZE(synchronized);
return entry;
}
int timeq_del(struct timeq_entry* entry) {
+ #ifdef HAVE_THREADS
+ if(!pthread_mutex_initialized) return 0;
+ #endif
SYNCHRONIZE(synchronized);
- struct timeq_entry *centry, *last = NULL;
- for(centry = timeq_events; centry; centry = centry->next) {
- if(centry == entry) {
- if(last)
- last->next = centry->next;
- else
- timeq_events = centry->next;
- if(centry->name)
- free(centry->name);
- free(centry);
- DESYNCHRONIZE(synchronized);
- return 1;
- } else {
- last = centry;
- }
- }
+ if(entry->next)
+ entry->next->prev = entry->prev;
+ if(entry->prev)
+ entry->prev->next = entry->next;
+ else
+ timeq_events = entry->next;
+ if(entry->name)
+ free(entry->name);
+ if(entry->iofd)
+ iohandler_close(entry->iofd);
+ free(entry);
DESYNCHRONIZE(synchronized);
- return 0;
+ return 1;
}
int timeq_del_name(char *name) {
SYNCHRONIZE(synchronized);
- struct timeq_entry *centry, *last = NULL;
- for(centry = timeq_events; centry; centry = centry->next) {
- if(centry->name && !stricmp(centry->name, name)) {
- if(last)
- last->next = centry->next;
- else
- timeq_events = centry->next;
- free(centry->name);
- free(centry);
- DESYNCHRONIZE(synchronized);
- return 1;
- } else {
- last = centry;
+ struct timeq_entry *entry;
+ int removed = 0;
+ for(entry = timeq_events; entry; entry = entry->next) {
+ if(entry->name && !stricmp(entry->name, name)) {
+ removed = timeq_del(entry);
+ break;
}
}
DESYNCHRONIZE(synchronized);
- return 0;
+ return removed;
}
int timeq_name_exists(char *name) {
void unregister_module_timers(int module_id) {
SYNCHRONIZE(synchronized);
- struct timeq_entry *centry, *next, *last = NULL;
- for(centry = timeq_events; centry; centry = next) {
- next = centry->next;
- if(centry->module_id == module_id) {
- if(last)
- last->next = centry->next;
- else
- timeq_events = centry->next;
- free(centry->name);
- free(centry);
- } else
- last = centry;
+ struct timeq_entry *entry, *next_entry;
+ for(entry = timeq_events; entry; entry = next_entry) {
+ next_entry = entry->next;
+ if(entry->module_id == module_id)
+ timeq_del(entry);
}
DESYNCHRONIZE(synchronized);
}