comparison src/protocols/icq/timeout.c @ 2086:424a40f12a6c

[gaim-migrate @ 2096] moving protocols from plugins/ to src/protocols. making it so that you can select which protocols are compiled statically. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Tue, 31 Jul 2001 01:00:39 +0000
parents
children
comparison
equal deleted inserted replaced
2085:7ebb4322f89b 2086:424a40f12a6c
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
3 /*
4 * $Id: timeout.c 2096 2001-07-31 01:00:39Z warmenhoven $
5 *
6 * Copyright (C) 1998-2001, Denis V. Dmitrienko <denis@null.net> and
7 * Bill Soudan <soudan@kde.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25 #include <stdlib.h>
26
27 #include "timeout.h"
28
29 icq_Timeout *icq_CurrentTimeout = NULL;
30 icq_List *icq_TimeoutList = NULL;
31
32 void (*icq_SetTimeout)(long length);
33
34 int icq_TimeoutCompare(icq_Timeout *t1, icq_Timeout *t2)
35 {
36 return (t1->expire_time - t2->expire_time);
37 }
38
39 icq_Timeout *icq_TimeoutNew(int length, icq_TimeoutHandler handler,
40 void *data)
41 {
42 icq_Timeout *t = (icq_Timeout *)malloc(sizeof(icq_Timeout));
43
44 if (t)
45 {
46 int count = icq_TimeoutList->count;
47
48 t->length = length;
49 t->handler = handler;
50 t->data = data;
51 t->expire_time = time(NULL) + length;
52 t->single_shot = 1;
53
54 icq_ListInsertSorted(icq_TimeoutList, t);
55
56 if (count == 0)
57 icq_TimeoutDoNotify();
58 }
59
60 return t;
61 }
62
63 void icq_TimeoutDelete(icq_Timeout *timeout)
64 {
65 icq_ListRemove(icq_TimeoutList, timeout);
66
67 /* if this was the timeout we were currently waiting on, move on
68 * to the next */
69 if (icq_CurrentTimeout == timeout)
70 {
71 icq_CurrentTimeout = NULL;
72 icq_TimeoutDoNotify();
73 }
74
75 free(timeout);
76 }
77
78 int _icq_HandleTimeout1(void *p, va_list data)
79 {
80 icq_Timeout *t = p;
81 int complete = 0;
82 time_t current_time = va_arg(data, time_t);
83 icq_List *expired_timeouts = va_arg(data, icq_List *);
84 (void)data;
85
86 if (t->expire_time <= current_time)
87 icq_ListEnqueue(expired_timeouts, t);
88 else
89 /* traversal is complete when we reach an expire time in the future */
90 complete = 1;
91
92 return complete;
93 }
94
95 int _icq_HandleTimeout2(void *p, va_list data)
96 {
97 icq_Timeout *t = p;
98 (void)data;
99
100 /* maybe a previously executed timeout caused us to be deleted, so
101 * make sure we're still around */
102 if (icq_ListFind(icq_TimeoutList, t))
103 (t->handler)(t->data);
104
105 return 0; /* traverse entire list */
106 }
107
108 int _icq_HandleTimeout3(void *p, va_list data)
109 {
110 icq_Timeout *t = p;
111 int complete = 0;
112 time_t current_time = va_arg(data, time_t);
113
114 if (t->expire_time <= current_time)
115 {
116 if (t->single_shot)
117 icq_TimeoutDelete(t);
118 else
119 t->expire_time = current_time + t->length;
120 }
121 else
122 /* traversal is complete when we reach an expire time in the future */
123 complete = 1;
124
125 return complete;
126 }
127
128 void icq_HandleTimeout()
129 {
130 time_t current_time = time(NULL);
131 icq_List *expired_timeouts = icq_ListNew();
132
133 icq_CurrentTimeout = NULL;
134
135 /* these three operations must be split up for the case where a
136 * timeout function causes timers to be deleted - this ensures
137 * we don't try to free any timers that have already been removed
138 * or corrupt the list traversal process */
139
140 /* determine which timeouts that have expired */
141 icq_ListTraverse(icq_TimeoutList, _icq_HandleTimeout1, current_time,
142 expired_timeouts);
143
144 /* call handler function for expired timeouts */
145 icq_ListTraverse(expired_timeouts, _icq_HandleTimeout2);
146
147 /* delete any expired timeouts */
148 icq_ListTraverse(icq_TimeoutList, _icq_HandleTimeout3, current_time);
149
150 /* if there's any timeouts left, notify the library client */
151 if (icq_TimeoutList->count)
152 icq_TimeoutDoNotify();
153
154 icq_ListDelete(expired_timeouts, NULL);
155 }
156
157 void icq_TimeoutDoNotify()
158 {
159 time_t length, current_time = time(NULL);
160
161 if (!icq_TimeoutList->count)
162 {
163 if (icq_SetTimeout)
164 (*icq_SetTimeout)(0);
165 return;
166 }
167
168 icq_CurrentTimeout = (icq_Timeout *)icq_ListFirst(icq_TimeoutList);
169 length = icq_CurrentTimeout->expire_time - current_time;
170
171 if (icq_SetTimeout)
172 (*icq_SetTimeout)(length);
173 }