summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_fork.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1999-11-19 21:29:03 +0000
committerphk <phk@FreeBSD.org>1999-11-19 21:29:03 +0000
commitb77d489a08d04efc9660b1caaa3a0db85601a98d (patch)
tree71b4b3a9700f7d0066e9f187937e6a486e88709a /sys/kern/kern_fork.c
parent0c40ec2d4cd03de7e036ebb4816388fdcadc265a (diff)
downloadFreeBSD-src-b77d489a08d04efc9660b1caaa3a0db85601a98d.zip
FreeBSD-src-b77d489a08d04efc9660b1caaa3a0db85601a98d.tar.gz
The at_exit and at_fork functions currently use a 'roll your own'
linked list to store the callbak routines. The patch converts the lists to queue(3) TAILQs, making the code slightly clearer and ensuring that callbacks are executed in FIFO order. Man page also updated as necesary. (discontinued use of M_TEMP malloc type while here anyway /phk) Submitted by: Jake Burkholder jake@checker.org PR: 14912
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r--sys/kern/kern_fork.c58
1 files changed, 27 insertions, 31 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 9268592..c12c965 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -65,6 +65,8 @@
#include <sys/user.h>
+static MALLOC_DEFINE(M_ATFORK, "atfork", "atfork callback");
+
static int fast_vfork = 1;
SYSCTL_INT(_kern, OID_AUTO, fast_vfork, CTLFLAG_RW, &fast_vfork, 0, "");
@@ -72,12 +74,13 @@ SYSCTL_INT(_kern, OID_AUTO, fast_vfork, CTLFLAG_RW, &fast_vfork, 0, "");
* These are the stuctures used to create a callout list for things to do
* when forking a process
*/
-typedef struct fork_list_element {
- struct fork_list_element *next;
+struct forklist {
forklist_fn function;
-} *fle_p;
+ TAILQ_ENTRY(forklist) next;
+};
-static fle_p fork_list;
+TAILQ_HEAD(forklist_head, forklist);
+static struct forklist_head fork_list = TAILQ_HEAD_INITIALIZER(fork_list);
#ifndef _SYS_SYSPROTO_H_
struct fork_args {
@@ -150,9 +153,7 @@ fork1(p1, flags, procp)
struct proc *newproc;
int count;
static int pidchecked = 0;
- fle_p ep ;
-
- ep = fork_list;
+ struct forklist *ep;
if ((flags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG))
return (EINVAL);
@@ -461,9 +462,8 @@ again:
* to adjust anything.
* What if they have an error? XXX
*/
- while (ep) {
+ TAILQ_FOREACH(ep, &fork_list, next) {
(*ep->function)(p1, p2, flags);
- ep = ep->next;
}
/*
@@ -505,48 +505,44 @@ again:
* However first make sure that it's not already there.
* Returns 0 on success or a standard error number.
*/
+
int
at_fork(function)
forklist_fn function;
{
- fle_p ep;
+ struct forklist *ep;
+#ifdef INVARIANTS
/* let the programmer know if he's been stupid */
if (rm_at_fork(function))
- printf("fork callout entry already present\n");
- ep = malloc(sizeof(*ep), M_TEMP, M_NOWAIT);
+ printf("WARNING: fork callout entry (%p) already present\n",
+ function);
+#endif
+ ep = malloc(sizeof(*ep), M_ATFORK, M_NOWAIT);
if (ep == NULL)
return (ENOMEM);
- ep->next = fork_list;
ep->function = function;
- fork_list = ep;
+ TAILQ_INSERT_TAIL(&fork_list, ep, next);
return (0);
}
/*
- * Scan the exit callout list for the given items and remove them.
- * Returns the number of items removed.
- * Theoretically this value 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_fork(function)
forklist_fn function;
{
- fle_p *epp, ep;
- int count;
+ struct forklist *ep;
- count= 0;
- epp = &fork_list;
- ep = *epp;
- while (ep) {
+ TAILQ_FOREACH(ep, &fork_list, next) {
if (ep->function == function) {
- *epp = ep->next;
- free(ep, M_TEMP);
- count++;
- } else {
- epp = &ep->next;
+ TAILQ_REMOVE(&fork_list, ep, next);
+ free(ep, M_ATFORK);
+ return(1);
}
- ep = *epp;
- }
- return (count);
+ }
+ return (0);
}
OpenPOWER on IntegriCloud