From owner-man-jp-reviewer@jp.FreeBSD.org Sun May 29 03:10:32 2005
Received: (from daemon@localhost)
	by castle.jp.FreeBSD.org (8.11.6p2+3.4W/8.11.3) id j4SIAWM17891;
	Sun, 29 May 2005 03:10:32 +0900 (JST)
	(envelope-from owner-man-jp-reviewer@jp.FreeBSD.org)
Received: from t-mta1.odn.ne.jp (mfep1.odn.ne.jp [143.90.131.179])
	by castle.jp.FreeBSD.org (8.11.6p2+3.4W/8.11.3) with ESMTP/inet id j4SIAVX17881
	for <man-jp-reviewer@jp.FreeBSD.org>; Sun, 29 May 2005 03:10:31 +0900 (JST)
	(envelope-from n-kogane@syd.odn.ne.jp)
Received: from kces6.koganemaru.co.jp ([220.212.166.90])
          by t-mta1.odn.ne.jp with ESMTP
          id <20050528181030792.DAGN.8089.t-mta1.odn.ne.jp@mta1.odn.ne.jp>
          for <man-jp-reviewer@jp.FreeBSD.org>;
          Sun, 29 May 2005 03:10:30 +0900
Received: by kces6.koganemaru.co.jp (Postfix, from userid 100)
	id 85569FCDE; Sun, 29 May 2005 03:11:33 +0900 (JST)
To: man-jp-reviewer@jp.FreeBSD.org
MIME-Version: 1.0 (generated by MimeKit/1.8)
Content-Type: text/plain; charset=ISO-2022-JP
Message-Id: <20050528181133.85569FCDE@kces6.koganemaru.co.jp>
From: n-kogane@syd.odn.ne.jp (Nobuyuki Koganemaru)
Reply-To: man-jp-reviewer@jp.FreeBSD.org
Precedence: list
Date: Sun, 29 May 2005 03:11:33 +0900
X-Sequence: man-jp-reviewer 4838
Subject: [man-jp-reviewer 4838] timeout.9 Update to 5.4RC4
Sender: owner-man-jp-reviewer@jp.FreeBSD.org
X-Originator: n-kogane@syd.odn.ne.jp
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+050320

$B>.6b4]$G$9!#(B

$B8e$m$K1QJ8$N:9J,$bIU$1$^$9!#(B
$B$"$d$7$$K]Lu$b$"$k$+$b$7$l$^$;$s$,!"$h$m$7$/$*4j$$$7$^$9!#(B

diff -u /dskg/JMAN4/doc/ja_JP.eucJP/man/man9/timeout.9 timeout.9
--- /dskg/JMAN4/doc/ja_JP.eucJP/man/man9/timeout.9	Wed Sep 22 06:00:59 2004
+++ timeout.9	Sat May 28 23:51:51 2005
@@ -34,10 +34,10 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" %FreeBSD: src/share/man/man9/timeout.9,v 1.23 2004/06/16 08:33:57 ru Exp %
+.\" %FreeBSD: src/share/man/man9/timeout.9,v 1.23.2.2 2005/03/21 23:01:30 iedowse Exp %
 .\" $FreeBSD: doc/ja_JP.eucJP/man/man9/timeout.9,v 1.5 2004/09/21 21:00:59 metal Exp $
 .\"
-.Dd September 10, 1996
+.Dd February 6, 2005
 .Dt TIMEOUT 9
 .Os
 .Sh $BL>>N(B
@@ -47,7 +47,10 @@
 .Nm callout_init ,
 .Nm callout_stop ,
 .Nm callout_drain ,
-.Nm callout_reset
+.Nm callout_reset ,
+.Nm callout_pending ,
+.Nm callout_active ,
+.Nm callout_deactivate
 .Nd $BL@<($5$l$?;~4VD9$N8e$N4X?t$N<B9T(B
 .Sh $B=q<0(B
 .In sys/types.h
@@ -74,6 +77,11 @@
 .Fn callout_drain "struct callout *c"
 .Ft void
 .Fn callout_reset "struct callout *c" "int ticks" "timeout_t *func" "void *arg"
+.Ft int
+.Fn callout_pending "struct callout *c"
+.Ft int
+.Fn callout_active "struct callout *c"
+.Fn callout_deactivate "struct callout *c"
 .Sh $B2r@b(B
 $B4X?t(B
 .Fn timeout
@@ -162,8 +170,8 @@
 .Fn untimeout
 $B$N$?$a$N(B O(1) $B<B9T;~4V$rDs6!$7$^$9!#(B
 timeout ($BLuCm(B: $B$*$h$S(B untimeout) $B$O(B
-.Fn splsoftclock
-$B$N>uBV$G(B
+.Va Giant
+$B%m%C%/$,J];}$5$l$F$$$k>uBV$G!"(B
 .Fn softclock
 $B$+$i<B9T$5$l$^$9!#(B
 $B=>$C$F!":FF~$+$iJ]8n$5$l$^$9!#(B
@@ -189,8 +197,8 @@
 $B0z?t$,(B 0 $B$N>l9g$K$O!"(Bcallout $B9=B$BN$O(B
 .Dq $B%^%k%A%W%m%;%C%5%;!<%U(B
 $B$G$"$k$H$O$_$J$5$l$^$;$s!#(B
-$B$9$J$o$A!"%8%c%$%"%s%H%m%C%/$,(B callout $B4X?t$N8F=P$7A0$K(B
-$B3MF@$5$l!"(Bcallout $B4X?t$,La$k$H$-$K2rJ|$5$l$k$h$&$K$7$^$9!#(B
+$B$9$J$o$A!"%8%c%$%"%s%H%m%C%/$,%3!<%k%"%&%H4X?t$N8F=P$7A0$K(B
+$B3MF@$5$l!"%3!<%k%"%&%H4X?t$,La$k$H$-$K2rJ|$5$l$k$h$&$K$7$^$9!#(B
 .Pp
 $B4X?t(B
 .Fn callout_stop
@@ -198,7 +206,13 @@
 $B%3!<%k%"%&%H$,J]N1Cf$N>l9g$K$O!"(B
 .Fn callout_stop
 $B$O(B 0 $B$G$J$$CM$rJV$7$^$9!#(B
-$B%3!<%k%"%&%H$,4{$K<B9T$5$l$?$+8=:_<B9TCf$N>l9g$K$O!"(B0 $B$,JV$5$l$^$9!#(B
+$B%3!<%k%"%&%H$,@_Dj$5$l$J$$$+4{$K<B9T$5$l$?$+8=:_<B9TCf$N>l9g$K$O!"(B
+0 $B$,JV$5$l$^$9!#(B
+$B$3$N4X?t$,8F$S=P$5$l$k$H$-!"%3!<%k%"%&%H$,(B
+.Va Giant
+$B%_%e!<%F%C%/%9(B (mutex) $B$K$h$C$FJ]8n$5$l$k>l9g$K$O!"(B
+.Va Giant
+$B$OJ];}$5$l$J$1$l$P$J$j$^$;$s!#(B
 .Pp
 $B4X?t(B
 .Fn callout_drain
@@ -208,14 +222,254 @@
 $B$3$N4X?t$O!"$=$N%3!<%k%"%&%H$,%V%m%C%/$9$k$+$b$7$l$J$$$"$i$f$k%m%C%/$r(B
 $BJ];}$7$F$$$k4V$O!"7h$7$F8F$S=P$5$l$F$O$J$j$^$;$s!#(B
 $B$5$b$J$$$H7k2L$H$7$F%G%C%I%m%C%/$7$^$9!#(B
+$B%3!<%k%"%&%H%5%V%7%9%F%`$,4{$K$3$N%3!<%k%"%&%H$r=hM}$7;O$a$?$J$i(B
+$B%3!<%k%"%&%H4X?t$,(B
+.Fn callout_drain
+$B$N<B9T$N4V$K8F$S=P$5$l$k$+$b$7$l$J$$$3$H$KCm0U$7$F$/$@$5$$!#(B
+$B$7$+$7$J$,$i!"%3!<%k%"%&%H%5%V%7%9%F%`$O!"(B
+.Fn callout_drain
+$B$,JV$kA0$K%3!<%k%"%&%H$,40A4$KDd;_$5$l$k$3$H$rJ]>Z$7$^$9!#(B
 .Pp
 $B4X?t(B
 .Fn callout_reset
 $B$O:G=i$K$=$N%3!<%k%"%&%H$rGQ;_$9$k$?$a$K(B
 .Fn callout_stop
-$B$r8F$S=P$7!"$=$l$+$i?7$7$$%3!<%k%"%&%H$r(B
+$B$HF1MM$N$3$H$r<B9T$7!"$=$l$+$i?7$7$$%3!<%k%"%&%H$r(B
 .Fn timeout
 $B$HF1$8N.57$G3NN)$7$^$9!#(B
+$B$3$N4X?t$,8F$S=P$5$l$k$H$-!"%3!<%k%"%&%H$,(B
+.Va Giant
+$B%_%e!<%F%C%/%9$K$h$C$FJ]8n$5$l$k>l9g$K$O!"(B
+.Va Giant
+$B$OJ];}$5$l$J$1$l$P$J$j$^$;$s!#(B
+.Pp
+$B%^%/%m(B
+.Fn callout_pending ,
+.Fn callout_active
+$B$*$h$S(B
+.Fn callout_deactivate
+$B$O%3!<%k%"%&%H$N8=:_$N>uBV$X$N%"%/%;%9$rDs6!$7$^$9!#(B
+$B$3$l$i$N%^%/%m$r?5=E$K;HMQ$9$l$P!"HsF14|%?%$%^5!9=$K(B
+$BFCM-$NB?$/$N6%9g>r7o$rHr$1$k$3$H$,$G$-$^$9!#(B
+$B$5$i$J$k>\:Y$K$D$$$F$O2<5-$N(B
+.Sx "$B6%9g>r7o$r2sHr$9$k(B"
+$B$r;2>H$7$F$@$5$$!#(B
+.Fn callout_pending
+$B%^%/%m$O!"%3!<%k%"%&%H$,(B
+.Em $BJ]N1Cf(B
+$B$G$"$k$+$I$&$+%A%'%C%/$7$^$9!#(B
+$B%3!<%k%"%&%H$O%?%$%`%"%&%H$,@_Dj$5$l$F$$$k$,;~4V$,$^$@E~Ce$7$F$$$J$$;~!"(B
+.Em $BJ]N1Cf(B
+$B$G$"$k$H8+$J$5$l$^$9!#(B
+$B$$$C$?$s%?%$%`%"%&%H;~4V$,Mh$F!"%3!<%k%"%&%H%5%V%7%9%F%`$,$3$N%3!<%k%"%&%H(B
+$B$r=hM}$7;O$a$l$P!"(B
+.Fn callout_pending
+$B$O$?$H$(%3!<%k%"%&%H4X?t$,<B9T$r=*N;$7$F(B ($B$^$?$O!";O$a$F(B) $B$$$J$/$F$b(B
+.Dv FALSE
+$B$rJV$9$3$H$KCm0U$7$F$/$@$5$$!#(B
+.\" even though = $B!A$K$b$+$+$o$i$:!"$?$H$(!A$H$7$F$b!"$?$H$(!A$G$b(B
+.Fn callout_active
+$B%^%/%m$O%3!<%k%"%&%H$,(B
+.Em $B%"%/%F%#%V(B
+$B$H$7$F%^!<%/$5$l$F$$$k$+$I$&$+%A%'%C%/$7!"(B
+.Fn callout_deactivate
+$B%^%/%m$O%3!<%k%"%&%H$N(B
+.Em $B%"%/%F%#%V(B
+$B%U%i%0$r%/%j%"$7$^$9!#(B
+$B%?%$%`%"%&%H$,@_Dj$5$l!"(B
+.Fn callout_stop
+$B$H(B
+.Fn callout_drain
+$B$N(B
+.Em $B%"%/%F%#%V(B
+$B%U%i%0$r%/%j%"$9$k$H$-!"(B
+$B%3!<%k%"%&%H%5%V%7%9%F%`$O(B
+.Em $B%"%/%F%#%V(B
+$B$H$7$F%3!<%k%"%&%H$r%^!<%/$7$^$9$,!"(B
+$BDL>o!"%3!<%k%"%&%H4X?t$N<B9T$K$h$C$F%3!<%k%"%&%H$N4|8B$,@Z$l$F$b!"(B
+$B$=$l$O%/%j%"(B
+.Em $B$5$l$^$;$s(B
+$B!#(B
+.Ss "$B6%9g>r7o$r2sHr$9$k(B"
+$B%3!<%k%"%&%H%5%V%7%9%F%`$O$=$l<+BN$N%?%$%^%3%s%F%-%9%H$+$i(B
+$B%3!<%k%"%&%H4X?t$r8F$S=P$7$^$9!#(B
+$B$"$k<o$NF14|$,$J$1$l$P!"%3!<%k%"%&%H4X?t$,F1;~$KJL$N%9%l%C%I$G%3!<%k%"%&%H(B
+$B$rDd;_$9$k$+$^$?$O%j%;%C%H$9$k;n$_$GF1;~$K8F$S=P$5$9$3$H$,$G$-$^$9!#(B
+$BFC$K!"%3!<%k%"%&%H4X?t$,$=$l$i$N:G=i$NF0:n$H$7$F(B
+$BDL>o%_%e!<%F%C%/%9$r<hF@$9$k$N$G!"(B
+$B%3!<%k%"%&%H4X?t$O4{$K8F$S=P$5$l$?$+$b$7$l$^$;$s$,!"(B
+$BJL$N%9%l%C%I$,%3!<%k%"%&%H$r%j%;%C%H$9$k$+$^$?$ODd;_$7$h$&$H$9$k;~$K(B
+$B$=$N%_%e!<%F%C%/%9$rBT$C$F%V%m%C%/$5$l$^$9!#(B
+.Pp
+$B%3!<%k%"%&%H%5%V%7%9%F%`$O$3$l$i$NF14|4X78$KBP=h$9$k$?$a$K(B
+$BB?$/$N%a%+%K%:%`$rDs6!$7$^$9!#(B
+.Bl -enum -offset indent
+.It
+.Fa mpsafe
+$B$r(B
+.Dv FALSE
+$B$K@_Dj$7$F(B
+.Fn callout_init
+$B$r;HMQ$9$k$3$H$G;XDj$5$l$k(B)
+.Va Giant
+$B%_%e!<%F%C%/%9$K$h$C$F%3!<%k%"%&%H$,J]8n$5$l$k>l9g$O!"(B
+$B$3$N%_%e!<%F%C%/%9$O6%9g>r7o$rHr$1$k$?$a$K;HMQ$5$l$^$9!#(B
+.Fn callout_stop
+$B$+(B
+.Fn callout_reset
+$B$r8F$S=P$9A0$K!"(B
+.Va Giant
+$B%_%e!<%F%C%/%9$O8F$S=P$7B&$K$h$C$F<hF@$5$l$J$1$l$P$J$i$J$/$F!"(B
+$B%3!<%k%"%&%H$,M=A[$I$*$j$K@5$7$/Dd;_$5$l$k$+$^$?$O%j%;%C%H$5$l$k(B
+$B$3$H$,J]>Z$5$l$^$9!#(B
+.\" as expected = $B0F$NDj!"M=A[$I$*$j(B($B$K(B)
+$B%3!<%k%"%&%H$+$=$N4XO"$N%_%e!<%F%C%/%9$rGK2u$9$kA0$K(B
+.Fn callout_drain
+$B$r;HMQ$9$kI,MW$,$^$@$"$k$3$H$KCm0U$7$F$/$@$5$$!#(B
+.It
+.Fn callout_stop
+$B$+$i$N%j%?!<%sCM$O!"%3!<%k%"%&%H$,:o=|$5$l$?$+$I$&$+$r<($7$^$9!#(B
+$B%3!<%k%"%&%H$,@_Dj$5$l!"(B
+$B%3!<%k%"%&%H4X?t$,$^$@<B9T$5$l$F$$$J$$$3$H$,$o$+$C$F$$$k>l9g$O!"(B
+$B%3!<%k%"%&%H4X?t$,8F$S=P$5$l$h$&$H$7$F$$$k$3$H$r<($9(B
+.Dv FALSE
+$B$NCM$,JV$5$l$^$9!#(B
+.\" about to = $B!T(Bbe $B!A!U$^$5$K!A$7$h$&$H$7$F$$$k(B
+$BNc$($P(B:
+.Bd -literal -offset indent
+if (sc->sc_flags & SCFLG_CALLOUT_RUNNING) {
+	if (callout_stop(&sc->sc_callout)) {
+		sc->sc_flags &= ~SCFLG_CALLOUT_RUNNING;
+		/* successfully stopped */
+	} else {
+		/*
+		 * callout has expired and callout
+		 * function is about to be executed
+		 */
+	}
+}
+.Ed
+.Pp
+.Fn callout_reset
+$B$,%3!<%k%"%&%H$rDd;_$7$?$+$I$&$+7hDj$9$k$?$a$N(B
+$BF1Ey$J%a%+%K%:%`$,$J$K$b$J$$$3$H$KCm0U$7$F$/$@$5$$!#(B
+.It
+.Fn callout_pending ,
+.Fn callout_active
+$B$*$h$S(B
+.Fn callout_deactivate
+$B%^%/%m$O6%9g>r7o$KBP=h$9$k$?$a$KF1;~$K;HMQ$9$k$3$H$,$G$-$^$9!#(B
+.\" work around = $BLdBj$K<h$j3]$+$k!"BP=h$9$k!"(B
+$B%3!<%k%"%&%H$N%?%$%`%"%&%H$,@_Dj$5$l$k$H$-!"%3!<%k%"%&%H%5%V%7%9%F%`$O(B
+$B$H$b$K(B
+.Em $B%"%/%F%#%V(B
+$B$H(B
+.Em $BJ]N1Cf(B
+$B$NN>J}$G%3!<%k%"%&%H$r%^!<%/$7$^$9!#(B
+$B%?%$%`%"%&%H;~4V$KC#$9$k$H$-!"%3!<%k%"%&%H%5%V%7%9%F%`$O(B
+.Em $BJ]N1Cf(B
+$B$N%U%i%0$r:G=i$K%/%j%"$9$k$3$H$K$h$C$F%3!<%k%"%&%H$r=hM}$7;O$a$^$9!#(B
+$B<!$K!"(B
+.Em $B%"%/%F%#%V(B
+$B%U%i%0$rJQ$($J$$$G%3!<%k%"%&%H4X?t$r8F$S=P$7$F!"(B
+$B%3!<%k%"%&%H4X?t$,La$C$?8e$G$5$((B
+.Em $B%"%/%F%#%V(B
+$B%U%i%0$r%/%j%"$7$^$;$s!#(B
+$B$3$3$G@bL@$5$l$?%a%+%K%:%`$O!"(B
+.Fn callout_deactivate
+$B%^%/%m$r;HMQ$9$k(B
+.Em $B%"%/%F%#%V(B
+$B%U%i%0$r%/%j%"$9$k$?$a$K%3!<%k%"%&%H4X?t<+BN$rI,MW$H$7$^$9!#(B
+.Fn callout_stop
+$B$H(B
+.Fn callout_drain
+$B4X?t$OLa$kA0$K!"(B
+$B>o$K(B
+.Em $B%"%/%F%#%V(B
+$B$H(B
+.Em $BJ]N1Cf(B
+$B%U%i%0$NN>J}$r%/%j%"$7$^$9!#(B
+.Pp
+.Fn callout_pending
+$B$,(B
+.Dv TRUE
+$B$rJV$9>l9g!"(B
+$B%3!<%k%"%&%H4X?t$O!":G=i$K(B
+.Em $BJ]N1Cf(B
+$B%U%i%0$r%A%'%C%/$7$FF0:n$J$7$GLa$k$Y$-$G$9!#(B
+$B$3$l$O!"%3!<%k%"%&%H$,%3!<%k%"%&%H4X?t$,8F$S=P$5$l$kD>A0$K(B
+.Fn callout_reset
+$B$r;HMQ$7$F:F%9%1%8%e!<%k$5$l$?$3$H$r<($7$^$9!#(B
+.Fn callout_active
+$B$,(B
+.Dv FALSE
+$B$rJV$9>l9g!"%3!<%k%"%&%H4X?t$OF1MM$KF0:n$J$7$GJV$k$Y$-$G$9!#(B
+$B$3$l$O!"%3!<%k%"%&%H$,Dd;_$5$l$?$3$H$r<($7$^$9!#(B
+$B:G8e$K!"%3!<%k%"%&%H4X?t$O!"(B
+.Em $B%"%/%F%#%V(B
+$B%U%i%0$r%/%j%"$9$k$?$a$K(B
+.Fn callout_deactivate
+$B$r8F$S=P$9$Y$-$G$9!#(B
+$BNc$($P(B:
+.Bd -literal -offset indent
+mtx_lock(&sc->sc_mtx);
+if (callout_pending(&sc->sc_callout)) {
+	/* callout was reset */
+	mtx_unlock(&sc->sc_mtx);
+	return;
+}
+if (!callout_active(&sc->sc_callout)) {
+	/* callout was stopped */
+	mtx_unlock(&sc->sc_mtx);
+	return;
+}
+callout_deactivate(&sc->sc_callout);
+/* rest of callout function */
+.Ed
+.Pp
+$B%_%e!<%F%C%/%9$,>e5-$G;HMQ$5$l$?$h$&$K(B
+$BE,@Z$JF14|$H$H$b$K!"$3$N%"%W%m!<%A$O!"(B
+.Fn callout_stop
+$B$H(B
+.Fn callout_reset
+$B4X?t$,$$$D$b6%9g$J$7$G;HMQ$5$l$k$N$r5v2D$7$^$9!#(B
+.\" together with = $B!A$H$H$b$K!"!A$K2C$($F(B
+$BNc$($P(B:
+.Bd -literal -offset indent
+mtx_lock(&sc->sc_mtx);
+callout_stop(&sc->sc_callout);
+/* The callout is effectively stopped now. */
+.Ed
+.Pp
+$B%3!<%k%"%&%H$,$^$@J]N1Cf$G$"$k>l9g!"$3$l$i$N4X?t$ODL>oF0:n$7$^$9$,!"(B
+$B%3!<%k%"%&%H$N=hM}$,4{$K;O$^$C$F$$$k>l9g!"(B
+$B%3!<%k%"%&%H4X?t$K$*$1$k%F%9%H$G$5$i$J$kF0:n$J$7$GLa$j$^$9!#(B
+$B%3!<%k%"%&%H$rDd;_$9$k$+$^$?$O%j%;%C%H$9$k$3$H$r3N<B$K$9$k(B
+$B%3!<%k%"%&%H4X?t$HB>$N%3!<%I$N4V$NF14|$O!"%3!<%k%"%&%H4X?t$,(B
+.Fn callout_deactivate
+$B8F$S=P$7$r=*$o$k$^$G$N4V!"7h$7$F;n$_$i$l$^$;$s!#(B
+.Pp
+$B$5$i$K!">e5-$N%F%/%K%C%/$O!"(B
+$B%3!<%k%"%&%H$,;v<B>eM-8z$K$5$l$k$+$^$?$OL58z$K$5$l$k$3$H$K$+$+$o$i$:(B
+.Em $B%"%/%F%#%V(B
+$B%U%i%0$,>o$KH?1G$9$k$3$H$r3N<B$K$7$^$9!#(B
+.Fn callout_active
+$B$,56$GLa$k>l9g!"%3!<%k%"%&%H$O;v<B>eL58z$K$5$l!"(B
+$B%3!<%k%"%&%H%5%V%7%9%F%`$,<B:]$K%3!<%k%"%&%H4X?t$r8F$S=P$=$&$H$7$F$$$k$N$G!"(B
+$B%3!<%k%"%&%H4X?t$OF0:n$J$7$GLa$j$^$9!#(B
+.\" since even if $B$O$I$&Lu$9$l$P$h$$$N$+(B ?
+.\" even if = $B$?$H$(!A$G$b(B
+.El
+.Pp
+$B%3!<%k%"%&%H$,:G8e$KDd;_$5$l$k$H$-$K!"(B
+$B9MN8$7$J$1$l$P$J$i$J$$:G8e$N(B 1 $B$D$N6%9g>r7o$,$"$j$^$9!#(B
+$B$3$N>l9g!"4{$KGK2u$5$l$k$+$^$?$O:F@8$5$l$?%G!<%?%*%V%8%'%/%H$K(B
+$B%"%/%;%9$9$kI,MW$,$"$k$+$b$7$l$J$$$N$G!"(B
+$B$=$l$O%3!<%k%"%&%H4X?t<+BN$,(B
+$BDd;_$5$l$?%3!<%k%"%&%H$r8!=P$9$k$5$;$k$?$a$K0BA4$G$J$$$+$b$7$l$^$;$s!#(B
+$B%3!<%k%"%&%H$,40A4$K=*$o$k$N$rJ]>Z$9$k$?$a$K$O!"(B
+.Fn callout_drain
+$B$X$N8F$S=P$7$,;HMQ$5$l$J$1$l$P$J$j$^$;$s!#(B
 .Sh $BLa$jCM(B
 .Fn timeout
 $B4X?t$O(B
@@ -226,7 +480,7 @@
 .Fn callout_stop
 $B$*$h$S(B
 .Fn callout_drain
-$B4X?t$O8F$S=P$5$l$?;~$K%3!<%k%"%&%H$,L$$@J]N1$N>l9g$K$O(B 0 $B0J30$r!"(B
+$B4X?t$O8F$S=P$5$l$?;~$K%3!<%k%"%&%H$,L$$@J]N1Cf$N>l9g$K$O(B 0 $B0J30$r!"(B
 $B$=$&$G$J$$>l9g$K$O(B 0 $B$rJV$7$^$9!#(B
 .Sh $BNr;K(B
 $B8=:_$N(B timeout $B$*$h$S(B untimeout $B%k!<%A%s$O(B

diff -u /dskg/JMAN4/5.3-RELEASE/man9/timeout.9 /dskg/JMAN4/5.4-RELEASE/man9/timeout.9
--- /dskg/JMAN4/5.3-RELEASE/man9/timeout.9	Fri Nov  5 10:26:14 2004
+++ /dskg/JMAN4/5.4-RELEASE/man9/timeout.9	Sun May  8 16:03:21 2005
@@ -34,9 +34,9 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/share/man/man9/timeout.9,v 1.23 2004/06/16 08:33:57 ru Exp $
+.\" $FreeBSD: src/share/man/man9/timeout.9,v 1.23.2.2 2005/03/21 23:01:30 iedowse Exp $
 .\"
-.Dd September 10, 1996
+.Dd February 6, 2005
 .Dt TIMEOUT 9
 .Os
 .Sh NAME
@@ -46,7 +46,10 @@
 .Nm callout_init ,
 .Nm callout_stop ,
 .Nm callout_drain ,
-.Nm callout_reset
+.Nm callout_reset ,
+.Nm callout_pending ,
+.Nm callout_active ,
+.Nm callout_deactivate
 .Nd execute a function after a specified length of time
 .Sh SYNOPSIS
 .In sys/types.h
@@ -73,6 +76,11 @@
 .Fn callout_drain "struct callout *c"
 .Ft void
 .Fn callout_reset "struct callout *c" "int ticks" "timeout_t *func" "void *arg"
+.Ft int
+.Fn callout_pending "struct callout *c"
+.Ft int
+.Fn callout_active "struct callout *c"
+.Fn callout_deactivate "struct callout *c"
 .Sh DESCRIPTION
 The function
 .Fn timeout
@@ -163,8 +171,9 @@
 .Fn untimeout .
 Timeouts are executed from
 .Fn softclock
-at
-.Fn splsoftclock .
+with the
+.Va Giant
+lock held.
 Thus they are protected from re-entrancy.
 .Pp
 The functions
@@ -199,8 +208,13 @@
 If the callout is pending, then
 .Fn callout_stop
 will return a non-zero value.
-If the callout has already been serviced or is currently being serviced,
-then zero will be returned.
+If the callout is not set, has already been serviced or is currently
+being serviced, then zero will be returned.
+If the callout is protected by the
+.Va Giant
+mutex, then
+.Va Giant
+must be held when this function is called.
 .Pp
 The function
 .Fn callout_drain
@@ -210,14 +224,248 @@
 already in progress.
 This function MUST NOT be called while holding any
 locks on which the callout might block, or deadlock will result.
+Note that if the callout subsystem has already begun processing this
+callout, then the callout function may be invoked during the execution of
+.Fn callout_drain .
+However, the callout subsystem does guarantee that the callout will be
+fully stopped before
+.Fn callout_drain
+returns.
 .Pp
 The function
 .Fn callout_reset
-first calls
+first performs the equivalent of
 .Fn callout_stop
 to disestablish the callout, and then establishes a new callout in the
 same manner as
 .Fn timeout .
+If the callout is protected by the
+.Va Giant
+mutex, then
+.Va Giant
+must be held when this function is called.
+.Pp
+The macros
+.Fn callout_pending ,
+.Fn callout_active
+and
+.Fn callout_deactivate
+provide access to the current state of the callout.
+Careful use of these macros can avoid many of the race conditions
+that are inherent in asynchronous timer facilities; see
+.Sx "Avoiding Race Conditions"
+below for further details.
+The
+.Fn callout_pending
+macro checks whether a callout is
+.Em pending ;
+a callout is considered
+.Em pending
+when a timeout has been set but the time has not yet arrived.
+Note that once the timeout time arrives and the callout subsystem
+starts to process this callout,
+.Fn callout_pending
+will return
+.Dv FALSE
+even though the callout function may not have finished (or even begun)
+executing.
+The
+.Fn callout_active
+macro checks whether a callout is marked as
+.Em active ,
+and the
+.Fn callout_deactivate
+macro clears the callout's
+.Em active
+flag.
+The callout subsystem marks a callout as
+.Em active
+when a timeout is set and it clears the
+.Em active
+flag in
+.Fn callout_stop
+and
+.Fn callout_drain ,
+but it
+.Em does not
+clear it when a callout expires normally via the execution of the
+callout function.
+.Ss "Avoiding Race Conditions"
+The callout subsystem invokes callout functions from its own timer
+context.
+Without some kind of synchronization it is possible that a callout
+function will be invoked concurrently with an attempt to stop or reset
+the callout by another thread.
+In particular, since callout functions typically acquire a mutex as
+their first action, the callout function may have already been invoked,
+but be blocked waiting for that mutex at the time that another thread
+tries to reset or stop the callout.
+.Pp
+The callout subsystem provides a number of mechanisms to address these
+synchronization concerns:
+.Bl -enum -offset indent
+.It
+If the callout is protected by the
+.Va Giant
+mutex (specified using
+.Fn callout_init
+with
+.Fa mpsafe
+set to
+.Dv FALSE ) ,
+then this mutex is used to avoid the race conditions.
+The
+.Va Giant
+mutex must be acquired by the caller before calling
+.Fn callout_stop
+or
+.Fn callout_reset
+and it is guaranteed that the callout will be correctly stopped
+or reset as expected.
+Note that it is still necessary to use
+.Fn callout_drain
+before destroying the callout or its associated mutex.
+.It
+The return value from
+.Fn callout_stop
+indicates whether or not the callout was removed.
+If it is known that the callout was set and the callout function has
+not yet executed, then a return value of
+.Dv FALSE
+indicates that the callout function is about to be called.
+For example:
+.Bd -literal -offset indent
+if (sc->sc_flags & SCFLG_CALLOUT_RUNNING) {
+	if (callout_stop(&sc->sc_callout)) {
+		sc->sc_flags &= ~SCFLG_CALLOUT_RUNNING;
+		/* successfully stopped */
+	} else {
+		/*
+		 * callout has expired and callout
+		 * function is about to be executed
+		 */
+	}
+}
+.Ed
+.Pp
+Note that there is no equivalent mechanism to determine whether or not
+.Fn callout_reset
+stopped the callout.
+.It
+The
+.Fn callout_pending ,
+.Fn callout_active
+and
+.Fn callout_deactivate
+macros can be used together to work around the race conditions.
+When a callout's timeout is set, the callout subsystem marks the
+callout as both
+.Em active
+and
+.Em pending .
+When the timeout time arrives, the callout subsystem begins processing
+the callout by first clearing the
+.Em pending
+flag.
+It then invokes the callout function without changing the
+.Em active
+flag, and does not clear the
+.Em active
+flag even after the callout function returns.
+The mechanism described here requires the callout function itself to
+clear the
+.Em active
+flag using the
+.Fn callout_deactivate
+macro.
+The
+.Fn callout_stop
+and
+.Fn callout_drain
+functions always clear both the
+.Em active
+and
+.Em pending
+flags before returning.
+.Pp
+The callout function should first check the
+.Em pending
+flag and return without action if
+.Fn callout_pending
+returns
+.Dv TRUE .
+This indicates that the callout was rescheduled using
+.Fn callout_reset
+just before the callout function was invoked.
+If
+.Fn callout_active
+returns
+.Dv FALSE
+then the callout function should also return without action.
+This indicates that the callout has been stopped.
+Finally, the callout function should call
+.Fn callout_deactivate
+to clear the
+.Em active
+flag.
+For example:
+.Bd -literal -offset indent
+mtx_lock(&sc->sc_mtx);
+if (callout_pending(&sc->sc_callout)) {
+	/* callout was reset */
+	mtx_unlock(&sc->sc_mtx);
+	return;
+}
+if (!callout_active(&sc->sc_callout)) {
+	/* callout was stopped */
+	mtx_unlock(&sc->sc_mtx);
+	return;
+}
+callout_deactivate(&sc->sc_callout);
+/* rest of callout function */
+.Ed
+.Pp
+Together with appropriate synchronization, such as the mutex used above,
+this approach permits the
+.Fn callout_stop
+and
+.Fn callout_reset
+functions to be used at any time without races.
+For example:
+.Bd -literal -offset indent
+mtx_lock(&sc->sc_mtx);
+callout_stop(&sc->sc_callout);
+/* The callout is effectively stopped now. */
+.Ed
+.Pp
+If the callout is still pending then these functions operate normally,
+but if processing of the callout has already begun then the tests in
+the callout function cause it to return without further action.
+Synchronization between the callout function and other code ensures that
+stopping or resetting the callout will never be attempted while the
+callout function is past the
+.Fn callout_deactivate
+call.
+.Pp
+The above technique additionally ensures that the
+.Em active
+flag always reflects whether the callout is effectively enabled or
+disabled.
+If
+.Fn callout_active
+returns false, then the callout is effectively disabled, since even if
+the callout subsystem is actually just about to invoke the callout
+function, the callout function will return without action.
+.El
+.Pp
+There is one final race condition that must be considered when a
+callout is being stopped for the last time.
+In this case it may not be safe to let the callout function itself
+detect that the callout was stopped, since it may need to access
+data objects that have already been destroyed or recycled.
+To ensure that the callout is completely finished, a call to
+.Fn callout_drain
+should be used.
 .Sh RETURN VALUES
 The
 .Fn timeout
--
($BM-(B)$B>.6b4]%3%s%T%e!<%?%(%s%8%K%"%j%s%0%5!<%S%9(B ($BJ!2,8)BgLn>k;T(B)
	$B>.6b4](B $B?.9,(B (Nobuyuki Koganemaru)
E-Mail: n-kogane@syd.odn.ne.jp
E-Mail: kogane@jp.FreeBSD.org
E-Mail: kogane@koganemaru.co.jp
URL: http://www.koganemaru.co.jp
