[IOMultiplexerV2] dev snapshot
[NextIRCd.git] / src / IOGarbageCollector.c
1 /* IOGarbageCollector.c - IOMultiplexer v2
2  * Copyright (C) 2014  Philipp Kreil (pk910)
3  * 
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License 
15  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
16  */
17 #define _IOHandler_internals
18 #include "IOInternal.h"
19 #include "IOHandler.h"
20 #include "IOGarbageCollector.h"
21
22 #define timeval_is_bigger(x,y) ((x.tv_sec > y.tv_sec) || (x.tv_sec == y.tv_sec && x.tv_usec > y.tv_usec))
23 #define timeval_is_smaler(x,y) ((x.tv_sec < y.tv_sec) || (x.tv_sec == y.tv_sec && x.tv_usec < y.tv_usec))
24
25 static struct IOGCObject {
26         void *object;
27         iogc_free *free_callback;
28         struct timeval timeout;
29         
30         struct IOGCObject *next;
31 };
32
33 #ifdef HAVE_PTHREAD_H
34 static pthread_mutex_t iogc_sync;
35 #endif
36
37 static int iogc_enabled = 1;
38 static struct timeval iogc_timeout;
39 static struct IOGCObject *first_object = NULL, *last_object = NULL;
40
41 void iogc_init() {
42         IOTHREAD_MUTEX_INIT(iogc_sync);
43         iogc_timeout.tv_usec = 0;
44         iogc_timeout.tv_sec = 10;
45 }
46
47
48 void iohandler_set_gc(int enabled) {
49         if(enabled)
50                 iogc_enabled = 1;
51         else
52                 iogc_enabled = 0;
53 }
54
55 void iogc_add(void *object) {
56         iogc_add_callback(object, NULL);
57 }
58
59 void iogc_add_callback(void *object, iogc_free *free_callback) {
60         if(!iogc_enabled) {
61                 if(free_callback)
62                         free_callback(object);
63                 else
64                         free(object);
65                 return;
66         }
67         struct IOGCObject *obj = malloc(sizeof(*obj));
68     if(!obj) {
69         iolog_trigger(IOLOG_ERROR, "could not allocate memory for IOGCObject in %s:%d", __FILE__, __LINE__);
70                 if(free_callback)
71                         free_callback(object);
72                 else
73                         free(object);
74         return;
75     }
76         obj->object = object;
77         obj->free_callback = free_callback;
78         gettimeofday(&obj->timeout, NULL);
79         
80 }
81
82 void iogc_exec() {
83         struct timeval ctime;
84         gettimeofday(&ctime, NULL);
85         
86         struct IOGCObject *obj, *next_obj;
87         for(obj = objects; obj; obj = next_obj) {
88                 if(timeval_is_smaler(obj->timeout, ctime)) {
89                         next_obj = obj->next;
90                         if(obj->free_callback)
91                                 obj->free_callback(obj->object);
92                         else
93                                 free(obj->object);
94                         free(obj);
95                 } else {
96                         objects = obj;
97                         break;
98                 }
99         }
100 }