comparison plugins/icq/timeout.c @ 1525:ba8e6e211af5

[gaim-migrate @ 1535] icqlib updates. beginnings of system logging. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Sat, 03 Mar 2001 00:26:04 +0000
parents 0ef6603d986e
children 8ed70631ed15
comparison
equal deleted inserted replaced
1524:a5c87ada5143 1525:ba8e6e211af5
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 2
3 #include "timeout.h" 3 #include "timeout.h"
4 4
5 icq_Timeout *icq_CurrentTimeout = NULL;
5 list *icq_TimeoutList = NULL; 6 list *icq_TimeoutList = NULL;
6 7
7 void (*icq_SetTimeout)(long length); 8 void (*icq_SetTimeout)(long length);
8 9
9 int icq_TimeoutCompare(icq_Timeout *t1, icq_Timeout *t2) 10 int icq_TimeoutCompare(icq_Timeout *t1, icq_Timeout *t2)
36 } 37 }
37 38
38 void icq_TimeoutDelete(icq_Timeout *timeout) 39 void icq_TimeoutDelete(icq_Timeout *timeout)
39 { 40 {
40 list_remove(icq_TimeoutList, timeout); 41 list_remove(icq_TimeoutList, timeout);
42
43 /* if this was the timeout we were currently waiting on, move on
44 * to the next */
45 if (icq_CurrentTimeout = timeout)
46 {
47 icq_CurrentTimeout = NULL;
48 icq_TimeoutDoNotify();
49 }
50
41 free(timeout); 51 free(timeout);
42 } 52 }
43 53
44 int _icq_HandleTimeout(void *p, va_list data) 54 int _icq_HandleTimeout1(void *p, va_list data)
45 { 55 {
46 icq_Timeout *t = p; 56 icq_Timeout *t = p;
57 int complete = 0;
47 time_t current_time = va_arg(data, time_t); 58 time_t current_time = va_arg(data, time_t);
48 int complete = 0; 59 list *expired_timeouts = va_arg(data, list *);
49 60
50 if (t->expire_time <= current_time) 61 if (t->expire_time <= current_time)
51 (*t->handler)(t->data); 62 list_enqueue(expired_timeouts, t);
52 else 63 else
53 /* traversal is complete when we reach an expire time in the future */ 64 /* traversal is complete when we reach an expire time in the future */
54 complete = 1; 65 complete = 1;
55 66
56 if (t->single_shot) 67 return complete;
57 icq_TimeoutDelete(t); 68 }
69
70 int _icq_HandleTimeout2(void *p, va_list data)
71 {
72 icq_Timeout *t = p;
73
74 /* maybe a previously executed timeout caused us to be deleted, so
75 * make sure we're still around */
76 if (list_find(icq_TimeoutList, t))
77 (t->handler)(t->data);
78 }
79
80 int _icq_HandleTimeout3(void *p, va_list data)
81 {
82 icq_Timeout *t = p;
83 int complete = 0;
84 time_t current_time = va_arg(data, time_t);
85
86 if (t->expire_time <= current_time)
87 {
88 if (t->single_shot)
89 icq_TimeoutDelete(t);
90 else
91 t->expire_time = current_time + t->length;
92 }
58 else 93 else
59 t->expire_time = current_time + t->length; 94 /* traversal is complete when we reach an expire time in the future */
95 complete = 1;
60 96
61 return complete; 97 return complete;
62 } 98 }
63 99
64 void icq_HandleTimeout() 100 void icq_HandleTimeout()
65 { 101 {
66 time_t current_time = time(NULL); 102 time_t current_time = time(NULL);
103 list *expired_timeouts = list_new();
67 104
68 /* call handler functions for all timeouts that have expired */ 105 icq_CurrentTimeout = NULL;
69 list_traverse(icq_TimeoutList, _icq_HandleTimeout, current_time); 106
107 /* these three operations must be split up, in the case where a
108 * timeout function causes timers to be deleted - this ensures
109 * we don't try to free any timers that have already been removed
110 * or corrupt the list traversal process */
111
112 /* determine which timeouts that have expired */
113 list_traverse(icq_TimeoutList, _icq_HandleTimeout1, current_time,
114 expired_timeouts);
115
116 /* call handler function for expired timeouts */
117 list_traverse(expired_timeouts, _icq_HandleTimeout2);
118
119 /* delete any expired timeouts */
120 list_traverse(icq_TimeoutList, _icq_HandleTimeout3, current_time);
70 121
71 if (icq_TimeoutList->count) 122 if (icq_TimeoutList->count)
72 icq_TimeoutDoNotify(); 123 icq_TimeoutDoNotify();
73 } 124 }
74 125
75 void icq_TimeoutDoNotify() 126 void icq_TimeoutDoNotify()
76 { 127 {
77 time_t current_time = time(NULL); 128 time_t length, current_time = time(NULL);
78 129
79 icq_Timeout *t = (icq_Timeout *)list_first(icq_TimeoutList); 130 if (!icq_TimeoutList->count)
80 long length = t->expire_time - current_time; 131 {
132 if (icq_SetTimeout)
133 (*icq_SetTimeout)(0);
134 return;
135 }
136
137 icq_CurrentTimeout = (icq_Timeout *)list_first(icq_TimeoutList);
138 length = icq_CurrentTimeout->expire_time - current_time;
139
81 if (icq_SetTimeout) 140 if (icq_SetTimeout)
82 (*icq_SetTimeout)(length); 141 (*icq_SetTimeout)(length);
83 } 142 }