From owner-freebsd-hackers@FreeBSD.ORG Sun Jul 13 20:08:22 2008 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 76A841065679 for ; Sun, 13 Jul 2008 20:08:22 +0000 (UTC) (envelope-from mbsd@pacbell.net) Received: from nlpi029.prodigy.net (nlpi029.sbcis.sbc.com [207.115.36.58]) by mx1.freebsd.org (Postfix) with ESMTP id 37F7E8FC16 for ; Sun, 13 Jul 2008 20:08:22 +0000 (UTC) (envelope-from mbsd@pacbell.net) Received: from mbook.home (adsl-69-236-103-127.dsl.pltn13.pacbell.net [69.236.103.127]) (authenticated bits=0) by nlpi029.prodigy.net (8.13.8 smtpauth/dk/8.13.8) with ESMTP id m6DJtMcD013014; Sun, 13 Jul 2008 14:55:38 -0500 Date: Sun, 13 Jul 2008 12:55:22 -0700 (PDT) From: =?ISO-8859-1?Q?Mikko_Ty=F6l=E4j=E4rvi?= To: Michael B Allen In-Reply-To: <78c6bd860807130813p4c28f930g1f3094241aa1f1b1@mail.gmail.com> Message-ID: References: <78c6bd860807130813p4c28f930g1f3094241aa1f1b1@mail.gmail.com> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-hackers Subject: Re: Pls sanity check my semtimedop(2) implementation X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Jul 2008 20:08:22 -0000 On Sun, 13 Jul 2008, Michael B Allen wrote: > Hi, > > Below is a semtimedop(2) implementation that I'm using for FreeBSD. I > was hoping someone could look it over and tell me if they think the > implementation is sound. > > The code seems to work ok but when stressing the FreeBSD build of my app > I have managed to provoke errors related to concurrency (usually when a > SIGALRM goes off). The Linux build works flawlessesly so I'm wondering > about this one critical function that is different. At the very least you need to check errno when semop() returns -1. Unless it is EINTR, you have other problems. Also, if there is any other code using the timer across this function call, you have race conditions between changing the signal handler and setting the timer. Even if there is no other use of the timer across this function, resetting the signal handler before disarming the timer leaves you open to the signal being handled by the default handler which will make the process exit. $.02, /Mikko > Is there any reason why I would want to use ITIMER_VIRTUAL / > SIGVTALRM instead of ITIMER_REAL / SIGALRM? > > Or perhaps I should be using a different implementation entirely? > > Mike > > int > _semtimedop(int semid, > struct sembuf *array, > size_t nops, > struct timespec *_timeout) > { > struct timeval timeout, before, after; > struct itimerval value, ovalue; > struct sigaction sa, osa; > int ret; > > if (_timeout) { > timeout.tv_sec = _timeout->tv_sec; > timeout.tv_usec = _timeout->tv_nsec / 1000; > > if (gettimeofday(&before, NULL) == -1) { > return -1; > } > > memset(&value, 0, sizeof value); > value.it_value = timeout; > > memset(&sa, 0, sizeof sa); > /* signal_print writes the signal info to a log file > */ > sa.sa_sigaction = signal_print; > sa.sa_flags = SA_SIGINFO; > sigemptyset(&sa.sa_mask); > sigaction(SIGALRM, &sa, &osa); > > if (setitimer(ITIMER_REAL, &value, &ovalue) == -1) { > sigaction(SIGALRM, &osa, NULL); > return -1; > } > } > > ret = semop(semid, array, nops); > > if (_timeout) { > sigaction(SIGALRM, &osa, NULL); > > if (setitimer(ITIMER_REAL, &ovalue, NULL) == -1) { > return -1; > } > } > > if (ret == -1) { > if (_timeout) { > struct timeval elapsed; > > if (gettimeofday(&after, NULL) == -1) { > return -1; > } > > _timeval_diff(&after, &before, &elapsed); > > if (timercmp(&elapsed, &timeout, >=)) > errno = EAGAIN; > } > > return -1; > } > > return 0; > } > _______________________________________________ > freebsd-hackers@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-hackers > To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org" >