From owner-svn-src-head@FreeBSD.ORG Sun Oct 16 21:30:15 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 94501106564A; Sun, 16 Oct 2011 21:30:15 +0000 (UTC) (envelope-from pjd@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 78CB48FC0A; Sun, 16 Oct 2011 21:30:15 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p9GLUFe4080627; Sun, 16 Oct 2011 21:30:15 GMT (envelope-from pjd@svn.freebsd.org) Received: (from pjd@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p9GLUFuw080624; Sun, 16 Oct 2011 21:30:15 GMT (envelope-from pjd@svn.freebsd.org) Message-Id: <201110162130.p9GLUFuw080624@svn.freebsd.org> From: Pawel Jakub Dawidek Date: Sun, 16 Oct 2011 21:30:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r226450 - head/lib/libutil X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 16 Oct 2011 21:30:15 -0000 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);