Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Oct 2011 21:30:15 +0000 (UTC)
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r226450 - head/lib/libutil
Message-ID:  <201110162130.p9GLUFuw080624@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pjd
Date: Sun Oct 16 21:30:15 2011
New Revision: 226450
URL: http://svn.freebsd.org/changeset/base/226450

Log:
  In pidfile_open(), if the pidfile is locked, but empty (PID is not stored yet)
  and the caller requested other process' PID by passing non-NULL pidptr
  argument, we will wait at most 100ms for the PID to show up in the file and if
  it won't, we will store -1 in *pidptr.
  
  From now on, pidfile_open() function never sets errno to EAGAIN on failure.
  
  In collaboration with:	des
  MFC after:		1 week

Modified:
  head/lib/libutil/pidfile.3
  head/lib/libutil/pidfile.c

Modified: head/lib/libutil/pidfile.3
==============================================================================
--- head/lib/libutil/pidfile.3	Sun Oct 16 21:01:42 2011	(r226449)
+++ head/lib/libutil/pidfile.3	Sun Oct 16 21:30:15 2011	(r226450)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 20, 2008
+.Dd October 16, 2011
 .Dt PIDFILE 3
 .Os
 .Sh NAME
@@ -59,11 +59,14 @@ The
 function opens (or creates) a file specified by the
 .Fa path
 argument and locks it.
-If a file can not be locked, a PID of an already running daemon is returned in
-the
+If
 .Fa pidptr
-argument (if it is not
-.Dv NULL ) .
+argument is not
+.Dv NULL
+and file can not be locked, the function will use it to store a PID of an
+already running daemon or
+.Li -1
+in case daemon did not write its PID yet.
 The function does not write process' PID into the file here, so it can be
 used before
 .Fn fork Ns ing
@@ -162,16 +165,18 @@ function will fail if:
 .It Bq Er EEXIST
 Some process already holds the lock on the given pidfile, meaning that a
 daemon is already running.
+If
+.Fa pidptr
+argument is not
+.Dv NULL
+the function will use it to store a PID of an already running daemon or
+.Li -1
+in case daemon did not write its PID yet.
 .It Bq Er ENAMETOOLONG
 Specified pidfile's name is too long.
 .It Bq Er EINVAL
 Some process already holds the lock on the given pidfile, but PID read
 from there is invalid.
-.It Bq Er EAGAIN
-Some process already holds the lock on the given pidfile, but the file
-is truncated.
-Most likely, the existing daemon is writing new PID into
-the file.
 .El
 .Pp
 The

Modified: head/lib/libutil/pidfile.c
==============================================================================
--- head/lib/libutil/pidfile.c	Sun Oct 16 21:01:42 2011	(r226449)
+++ head/lib/libutil/pidfile.c	Sun Oct 16 21:30:15 2011	(r226450)
@@ -119,20 +119,20 @@ pidfile_open(const char *path, mode_t mo
 	fd = flopen(pfh->pf_path,
 	    O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK, mode);
 	if (fd == -1) {
-		count = 0;
-		rqtp.tv_sec = 0;
-		rqtp.tv_nsec = 5000000;
 		if (errno == EWOULDBLOCK && pidptr != NULL) {
-		again:
-			errno = pidfile_read(pfh->pf_path, pidptr);
-			if (errno == 0)
-				errno = EEXIST;
-			else if (errno == EAGAIN) {
-				if (++count <= 3) {
-					nanosleep(&rqtp, 0);
-					goto again;
-				}
+			count = 20;
+			rqtp.tv_sec = 0;
+			rqtp.tv_nsec = 5000000;
+			for (;;) {
+				errno = pidfile_read(pfh->pf_path, pidptr);
+				if (errno != EAGAIN || --count == 0)
+					break;
+				nanosleep(&rqtp, 0);
 			}
+			if (errno == EAGAIN)
+				*pidptr = -1;
+			if (errno == 0 || errno == EAGAIN)
+				errno = EEXIST;
 		}
 		free(pfh);
 		return (NULL);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110162130.p9GLUFuw080624>