Watt-32 tcp/ip  2.2 dev-rel.10
run.c
1 
2 #include <stdio.h>
3 #include <stdlib.h>
4 
5 #include "wattcp.h"
6 #include "pcdbug.h"
7 #include "misc.h"
8 #include "timer.h"
9 #include "run.h"
10 
18 struct run_list {
19  _VoidProc func;
20  const char *name;
21  int order;
22  const char *file;
23  unsigned line;
24  BOOL running; /* Prevent reentry. Uses in daemon_list[] only. */
25  };
26 
27 static struct run_list start_list [40];
28 static struct run_list exit_list [40];
29 static struct run_list daemon_list [20]; /* List of background processes */
30 
31 static int num_start_func_inserts = 0;
32 static int num_exit_func_inserts = 0;
33 
34 static DWORD daemon_timer = 0UL; /* When to run "background" processes */
35 
36 static int MS_CDECL list_compare (const struct run_list *a, const struct run_list *b)
37 {
38  return (a->order - b->order);
39 }
40 
44 int startup_add (_VoidProc func, const char *name, int order,
45  const char *file, unsigned line)
46 {
47  int i;
48 
49  for (i = 0; i < num_start_func_inserts; i++)
50  {
51  if (!start_list[i].func)
52  continue;
53 
54  if (start_list[i].func == func)
55  goto modify;
56 
57  if (start_list[i].order == order)
58  {
59  CONSOLE_MSG (0, ("%s(%u): startup_add (\"%s\",%d): order already "
60  "in start_list[]\n", file, line, name, order));
61  return (-1);
62  }
63  }
64 
65  WATT_ASSERT (num_start_func_inserts < DIM(start_list));
66  i = num_start_func_inserts++;
67 
68 modify:
69  start_list[i].func = func;
70  start_list[i].name = name;
71  start_list[i].order = order;
72  start_list[i].file = file;
73  start_list[i].line = line;
74 
75 #if 1
76  qsort (&start_list, DIM(start_list), sizeof(start_list[0]),
77  (CmpFunc)list_compare);
78 #else
79  if (i > 0)
80  qsort (&start_list, i, sizeof(start_list[0]), (CmpFunc)list_compare);
81 #endif
82 
83  return (num_start_func_inserts);
84 }
85 
89 int rundown_add (_VoidProc func, const char *name, int order,
90  const char *file, unsigned line)
91 {
92  int i;
93 
94  for (i = 0; i < num_exit_func_inserts; i++)
95  {
96  if (!exit_list[i].func)
97  continue;
98 
99  if (exit_list[i].func == func)
100  goto modify;
101 
102  if (exit_list[i].order == order)
103  {
104  CONSOLE_MSG (0, ("%s(%u): rundown_add (\"%s\",%d): order already "
105  "in exit_list[]\n", file, line, name, order));
106  return (-1);
107  }
108  }
109 
110  WATT_ASSERT (num_exit_func_inserts < DIM(exit_list));
111  i = num_exit_func_inserts++;
112 
113 modify:
114  exit_list[i].func = func;
115  exit_list[i].name = name;
116  exit_list[i].order = order;
117  exit_list[i].file = file;
118  exit_list[i].line = line;
119 
120 #if 1
121  qsort (&exit_list, DIM(exit_list), sizeof(exit_list[0]),
122  (CmpFunc)list_compare);
123 #else
124  if (i > 0)
125  qsort (&exit_list, i, sizeof(exit_list[0]), (CmpFunc)list_compare);
126 #endif
127 
128  return (num_exit_func_inserts);
129 }
130 
134 void rundown_run (void)
135 {
136  struct run_list *oe;
137  _VoidProc func;
138  int i;
139 
140  for (i = 0, oe = exit_list; i < DIM(exit_list); i++, oe++)
141  {
142  if (!oe->func)
143  continue;
144 
145  CONSOLE_MSG (3, ("Calling rundown-func `%s' at order %d\n",
146  oe->name, oe->order));
147  func = oe->func;
148  oe->func = NULL; /* don't call it again */
149  (*func)();
150  }
151 }
152 
153 #if defined(USE_DEBUG)
154 
157 void rundown_dump (void)
158 {
159  const struct run_list *oe;
160  int i, num_active;
161 
162  (*_printf) ("rundown_dump():\n");
163  for (i = num_active = 0, oe = exit_list; i < DIM(exit_list); i++, oe++)
164  {
165  if (!oe->func)
166  continue;
167  CONSOLE_MSG (0, (" order %3d: `%s' called from %s (%u)\n",
168  oe->order, oe->name, oe->file, oe->line));
169  num_active++;
170  }
171  CONSOLE_MSG (0, (" %s\n", num_active == i ? "possible overflow" : "okay"));
172 }
173 #endif
174 
175 #ifdef NOT_USED
176 
179 void exit_misc (void)
180 {
181  num_exit_func_inserts = 0;
182 }
183 #endif
184 
185 
194 int daemon_add (_VoidProc func, const char *name,
195  const char *file, unsigned line)
196 {
197  struct run_list *r;
198  int i;
199 
200  /* see if the daemon is already in the list */
201  for (i = 0, r = daemon_list; i < DIM(daemon_list); i++, r++)
202  if (r->func && r->func == func)
203  {
204  CONSOLE_MSG (3, ("\ndaemon_add(): daemon exists\n"));
205  return (1); /* operation can proceed normally */
206  }
207 
208  for (i = 0, r = daemon_list; i < DIM(daemon_list); i++, r++)
209  if (!r->func)
210  {
211  r->func = func;
212  r->name = name;
213  r->running = FALSE;
214  return (1);
215  }
216  ARGSUSED (file);
217  ARGSUSED (line);
218  return (0); /* didn't find a free slot */
219 }
220 
225 int daemon_del (_VoidProc func, const char *name,
226  const char *file, unsigned line)
227 {
228  struct run_list *r;
229  int i;
230 
231  for (i = 0, r = daemon_list; i < DIM(daemon_list); i++, r++)
232  if (!func || func == r->func)
233  {
234  r->func = NULL;
235  r->running = FALSE;
236  return (1);
237  }
238  ARGSUSED (name);
239  ARGSUSED (file);
240  ARGSUSED (line);
241  return (0); /* didn't find the daemon */
242 }
243 
244 /* UPDATE: 26FEB2006 psuggs@pobox.com
245  * Shutdown daemons and clear the list
246  */
247 void daemon_clear (void)
248 {
249  daemon_del (NULL, NULL, NULL, 0);
250 }
251 
256 int daemon_run (void)
257 {
258  int rc = 0;
259 
260  if (daemon_timer == 0UL || chk_timeout(daemon_timer))
261  {
262  struct run_list *r;
263  int i;
264 
265  for (i = 0, r = daemon_list; i < DIM(daemon_list); i++, r++)
266  if (r->func && !r->running)
267  {
268  if (r->name)
269  CONSOLE_MSG (3, ("Running daemon %d (%s)\n", i, r->name));
270  else CONSOLE_MSG (3, ("Running daemon %d (%p)\n", i, r->func));
271  r->running = TRUE;
272  (*r->func)();
273  r->running = FALSE;
274  rc++;
275  }
276  }
277  daemon_timer = set_timeout (DAEMON_PERIOD);
278  return (rc);
279 }
280 
281 /*
282  * Old names for above. Keep these public.
283  */
284 int W32_CALL addwattcpd (VoidProc func)
285 {
286  return daemon_add ((_VoidProc)func, NULL, NULL, 0);
287 }
288 
289 int W32_CALL delwattcpd (VoidProc func)
290 {
291  return daemon_del ((_VoidProc)func, NULL, NULL, 0);
292 }
293 
Register an on-startup/at-exit function.
Definition: run.c:18
Core definitions.
DWORD W32_CALL set_timeout(DWORD msec)
Return time for when given timeout (msec) expires.
Definition: timer.c:503
BOOL W32_CALL chk_timeout(DWORD value)
Check if milli-sec value has expired:
Definition: timer.c:547