summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_exit.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_exit.c')
-rw-r--r--sys/kern/kern_exit.c57
1 files changed, 27 insertions, 30 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 6c00e43..abbe9de 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -75,17 +75,20 @@
/* Required to be non-static for SysVR4 emulator */
MALLOC_DEFINE(M_ZOMBIE, "zombie", "zombie proc status");
+static MALLOC_DEFINE(M_ATEXIT, "atexit", "atexit callback");
+
static int wait1 __P((struct proc *, struct wait_args *, int));
/*
* callout list for things to do at exit time
*/
-typedef struct exit_list_element {
- struct exit_list_element *next;
+struct exitlist {
exitlist_fn function;
-} *ele_p;
+ TAILQ_ENTRY(exitlist) next;
+};
-static ele_p exit_list;
+TAILQ_HEAD(exit_list_head, exitlist);
+static struct exit_list_head exit_list = TAILQ_HEAD_INITIALIZER(exit_list);
/*
* exit --
@@ -115,7 +118,7 @@ exit1(p, rv)
{
register struct proc *q, *nq;
register struct vmspace *vm;
- ele_p ep = exit_list;
+ struct exitlist *ep;
if (p->p_pid == 1) {
printf("init died (signal %d, exit %d)\n",
@@ -154,10 +157,8 @@ exit1(p, rv)
* e.g. SYSV IPC stuff
* XXX what if one of these generates an error?
*/
- while (ep) {
+ TAILQ_FOREACH(ep, &exit_list, next)
(*ep->function)(p);
- ep = ep->next;
- }
if (p->p_flag & P_PROFIL)
stopprofclock(p);
@@ -580,49 +581,45 @@ proc_reparent(child, parent)
* However first make sure that it's not already there.
* returns 0 on success.
*/
+
int
at_exit(function)
exitlist_fn function;
{
- ele_p ep;
+ struct exitlist *ep;
+#ifdef INVARIANTS
/* Be noisy if the programmer has lost track of things */
if (rm_at_exit(function))
- printf("exit callout entry already present\n");
- ep = malloc(sizeof(*ep), M_TEMP, M_NOWAIT);
+ printf("WARNING: exit callout entry (%p) already present\n",
+ function);
+#endif
+ ep = malloc(sizeof(*ep), M_ATEXIT, M_NOWAIT);
if (ep == NULL)
return (ENOMEM);
- ep->next = exit_list;
ep->function = function;
- exit_list = ep;
+ TAILQ_INSERT_TAIL(&exit_list, ep, next);
return (0);
}
+
/*
- * Scan the exit callout list for the given items and remove them.
- * Returns the number of items removed.
- * Logically this can only be 0 or 1.
+ * Scan the exit callout list for the given item and remove it.
+ * Returns the number of items removed (0 or 1)
*/
int
rm_at_exit(function)
exitlist_fn function;
{
- ele_p *epp, ep;
- int count;
+ struct exitlist *ep;
- count = 0;
- epp = &exit_list;
- ep = *epp;
- while (ep) {
+ TAILQ_FOREACH(ep, &exit_list, next) {
if (ep->function == function) {
- *epp = ep->next;
- free(ep, M_TEMP);
- count++;
- } else {
- epp = &ep->next;
+ TAILQ_REMOVE(&exit_list, ep, next);
+ free(ep, M_ATEXIT);
+ return(1);
}
- ep = *epp;
- }
- return (count);
+ }
+ return (0);
}
void check_sigacts (void)
OpenPOWER on IntegriCloud