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
This commit is contained in:
parent
b6faf3cfdb
commit
e8cc80c0a0
@ -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
|
||||
|
@ -119,20 +119,20 @@ pidfile_open(const char *path, mode_t mode, pid_t *pidptr)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user