[IOMultiplexerV2] alpha
[NextIRCd.git] / src / IOHandler / 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 #include "IOLog.h"
22
23 #include <sys/time.h>
24 #include <stdlib.h>
25
26 struct IOGCObject {
27         void *object;
28         iogc_free *free_callback;
29         struct timeval timeout;
30         
31         struct IOGCObject *next;
32 };
33
34 static int iogc_enabled = 1;
35 static struct timeval iogc_timeout;
36 static struct IOGCObject *first_object = NULL, *last_object = NULL;
37
38 void iogc_init() {
39         iogc_timeout.tv_usec = 0;
40         iogc_timeout.tv_sec = 10;
41 }
42
43
44 void iohandler_set_gc(int enabled) {
45         if(enabled)
46                 iogc_enabled = 1;
47         else
48                 iogc_enabled = 0;
49 }
50
51 void iogc_add(void *object) {
52         iogc_add_callback(object, NULL);
53 }
54
55 void iogc_add_callback(void *object, iogc_free *free_callback) {
56         if(!iogc_enabled) {
57                 if(free_callback)
58                         free_callback(object);
59                 else
60                         free(object);
61                 return;
62         }
63         struct IOGCObject *obj = malloc(sizeof(*obj));
64     if(!obj) {
65         iolog_trigger(IOLOG_ERROR, "could not allocate memory for IOGCObject in %s:%d", __FILE__, __LINE__);
66                 if(free_callback)
67                         free_callback(object);
68                 else
69                         free(object);
70         return;
71     }
72         obj->object = object;
73         obj->free_callback = free_callback;
74         gettimeofday(&obj->timeout, NULL);
75         obj->timeout.tv_sec += IOGC_TIMEOUT;
76         
77         obj->next = NULL;
78         if(last_object)
79                 last_object->next = obj;
80         else
81                 first_object = obj;
82         last_object = obj;
83 }
84
85 void iogc_exec() {
86         struct timeval now;
87         gettimeofday(&now, NULL);
88         
89         struct IOGCObject *obj, *next_obj;
90         for(obj = first_object; obj; obj = next_obj) {
91                 if(timeval_is_smaler(obj->timeout, now)) {
92                         next_obj = obj->next;
93                         if(obj->free_callback)
94                                 obj->free_callback(obj->object);
95                         else
96                                 free(obj->object);
97                         free(obj);
98                 } else
99                         break;
100         }
101         first_object = obj;
102 }