1 | #ifndef TIMERTHREAD_H |
---|
2 | #define TIMERTHREAD_H |
---|
3 | |
---|
4 | struct stimerthread* gettimer(struct stimerthread* timernode) |
---|
5 | { |
---|
6 | //debug(1000, "in"); |
---|
7 | struct stimerthread *node = stimerthread; |
---|
8 | |
---|
9 | while(node != NULL) |
---|
10 | { |
---|
11 | if(node == timernode) |
---|
12 | { |
---|
13 | //debug(1000, "out"); |
---|
14 | return node; |
---|
15 | } |
---|
16 | |
---|
17 | node = node->next; |
---|
18 | } |
---|
19 | debug(100, "timerthread not found (timer=%p)", timernode); |
---|
20 | return NULL; |
---|
21 | } |
---|
22 | |
---|
23 | struct stimerthread* addtimer(void* func, int aktion, int delay, int count, void* param1, void* param2, struct stimerthread* last) |
---|
24 | { |
---|
25 | debug(1000, "in"); |
---|
26 | struct stimerthread *newnode = NULL, *prev = NULL, *node = stimerthread; |
---|
27 | |
---|
28 | newnode = (struct stimerthread*)malloc(sizeof(struct stimerthread)); |
---|
29 | if(newnode == NULL) |
---|
30 | { |
---|
31 | err("no memory"); |
---|
32 | return NULL; |
---|
33 | } |
---|
34 | |
---|
35 | memset(newnode, 0, sizeof(struct stimerthread)); |
---|
36 | |
---|
37 | newnode->func = func; |
---|
38 | newnode->aktion = aktion; |
---|
39 | newnode->delay = delay; |
---|
40 | newnode->count = count; |
---|
41 | newnode->param1 = param1; |
---|
42 | newnode->param2 = param2; |
---|
43 | |
---|
44 | m_lock(&status.timerthreadmutex, 6); |
---|
45 | if(last == NULL) |
---|
46 | { |
---|
47 | while(node != NULL) |
---|
48 | { |
---|
49 | prev = node; |
---|
50 | node = node->next; |
---|
51 | } |
---|
52 | } |
---|
53 | else |
---|
54 | { |
---|
55 | prev = last; |
---|
56 | node = last->next; |
---|
57 | } |
---|
58 | |
---|
59 | if(prev == NULL) |
---|
60 | stimerthread = newnode; |
---|
61 | else |
---|
62 | prev->next = newnode; |
---|
63 | newnode->next = node; |
---|
64 | |
---|
65 | m_unlock(&status.timerthreadmutex, 6); |
---|
66 | debug(1000, "out"); |
---|
67 | return newnode; |
---|
68 | } |
---|
69 | |
---|
70 | void deltimer(struct stimerthread *tnode) |
---|
71 | { |
---|
72 | debug(1000, "in"); |
---|
73 | int i = 0; |
---|
74 | void* threadstatus; |
---|
75 | |
---|
76 | m_lock(&status.timerthreadmutex, 6); |
---|
77 | struct stimerthread *node = stimerthread, *prev = stimerthread; |
---|
78 | |
---|
79 | while(node != NULL) |
---|
80 | { |
---|
81 | if(node == tnode) |
---|
82 | { |
---|
83 | //stop timer sub thread |
---|
84 | node->aktion = STOP; |
---|
85 | while(node->status != DEACTIVE) |
---|
86 | { |
---|
87 | usleep(100000); |
---|
88 | i++; if(i > 20) break; |
---|
89 | } |
---|
90 | |
---|
91 | if(i > 20) |
---|
92 | { |
---|
93 | err("detect hanging timer sub thread"); |
---|
94 | } |
---|
95 | else if(node->count < 0 && node->thread != '\0') |
---|
96 | pthread_join(node->thread, &threadstatus); |
---|
97 | pthread_attr_destroy(&node->attr); |
---|
98 | |
---|
99 | if(node == stimerthread) |
---|
100 | stimerthread = node->next; |
---|
101 | else |
---|
102 | prev->next = node->next; |
---|
103 | |
---|
104 | free(node); |
---|
105 | node = NULL; |
---|
106 | break; |
---|
107 | } |
---|
108 | |
---|
109 | prev = node; |
---|
110 | node = node->next; |
---|
111 | } |
---|
112 | |
---|
113 | m_unlock(&status.timerthreadmutex, 6); |
---|
114 | debug(1000, "out"); |
---|
115 | } |
---|
116 | |
---|
117 | //flag 0 = stop all |
---|
118 | //flag 1 = stop only threads with thread->flag bit 0 = 1 |
---|
119 | void freetimer(int flag) |
---|
120 | { |
---|
121 | debug(1000, "in"); |
---|
122 | struct stimerthread *node = stimerthread, *prev = stimerthread; |
---|
123 | |
---|
124 | while(node != NULL) |
---|
125 | { |
---|
126 | prev = node; |
---|
127 | node = node->next; |
---|
128 | if(prev != NULL) |
---|
129 | { |
---|
130 | if(flag == 0) |
---|
131 | deltimer(prev); |
---|
132 | else if(flag == 1 && checkbit(prev->flag, 0) == 1) |
---|
133 | deltimer(prev); |
---|
134 | } |
---|
135 | } |
---|
136 | debug(1000, "out"); |
---|
137 | } |
---|
138 | |
---|
139 | void* timerthreadsubfunc(void *param) |
---|
140 | { |
---|
141 | debug(1000, "in"); |
---|
142 | int count = 0; |
---|
143 | struct stimerthread* node = (struct stimerthread*)param; |
---|
144 | |
---|
145 | if(param == NULL) |
---|
146 | { |
---|
147 | debug(1000, "out -> NULL detect"); |
---|
148 | pthread_exit(NULL); |
---|
149 | } |
---|
150 | |
---|
151 | node->status = ACTIVE; |
---|
152 | while(node->aktion != STOP) |
---|
153 | { |
---|
154 | if(node->aktion != PAUSE) |
---|
155 | { |
---|
156 | node->status = ACTIVE; |
---|
157 | node->func(node, node->param1, node->param2); |
---|
158 | node->notfirst = 1; |
---|
159 | if(node->count > -1 && node->aktion != PAUSE) node->count--; |
---|
160 | if(node->count == 0) break; |
---|
161 | } |
---|
162 | else |
---|
163 | node->status = INPAUSE; |
---|
164 | |
---|
165 | if(node->delay > 1000) |
---|
166 | { |
---|
167 | count = node->delay; |
---|
168 | while(count > 1000) |
---|
169 | { |
---|
170 | usleep(1000000); |
---|
171 | count = count - 1000; |
---|
172 | if(node->aktion == STOP || node->aktion == PAUSE) count = 0; |
---|
173 | } |
---|
174 | usleep(count); |
---|
175 | } |
---|
176 | else |
---|
177 | usleep(node->delay * 1000); |
---|
178 | } |
---|
179 | node->status = DEACTIVE; |
---|
180 | |
---|
181 | if(node->count > -1) deltimer(node); |
---|
182 | |
---|
183 | debug(1000, "out"); |
---|
184 | pthread_exit(NULL); |
---|
185 | } |
---|
186 | |
---|
187 | void* timerthreadfunc(void *param) |
---|
188 | { |
---|
189 | debug(1000, "in"); |
---|
190 | int ret = 0; |
---|
191 | struct stimerthread* node = stimerthread; |
---|
192 | |
---|
193 | status.timerthreadstatus = ACTIVE; |
---|
194 | while(status.timerthreadaktion != STOP) |
---|
195 | { |
---|
196 | if(status.timerthreadaktion != PAUSE) |
---|
197 | { |
---|
198 | status.timerthreadstatus = ACTIVE; |
---|
199 | node = stimerthread; |
---|
200 | while(node != NULL) |
---|
201 | { |
---|
202 | if(node->status == DEACTIVE && node->aktion == START) |
---|
203 | { |
---|
204 | pthread_attr_init(&node->attr); |
---|
205 | pthread_attr_setstacksize(&node->attr, 50000); |
---|
206 | pthread_attr_setdetachstate(&node->attr, PTHREAD_CREATE_JOINABLE); |
---|
207 | node->status = ACTIVE; |
---|
208 | debug(10, "start timer sub thread"); |
---|
209 | ret = pthread_create(&node->thread, &node->attr, timerthreadsubfunc, (void*)node); |
---|
210 | if(ret) |
---|
211 | { |
---|
212 | node->status = ERROR; |
---|
213 | perr("create timer sub thread"); |
---|
214 | pthread_attr_destroy(&node->attr); |
---|
215 | } |
---|
216 | node = stimerthread; |
---|
217 | } |
---|
218 | node = node->next; |
---|
219 | } |
---|
220 | |
---|
221 | } |
---|
222 | else |
---|
223 | status.timerthreadstatus = INPAUSE; |
---|
224 | |
---|
225 | usleep(1 * 1000000); |
---|
226 | } |
---|
227 | status.timerthreadstatus = DEACTIVE; |
---|
228 | |
---|
229 | debug(1000, "out"); |
---|
230 | pthread_exit(NULL); |
---|
231 | } |
---|
232 | |
---|
233 | #endif |
---|