From owner-svn-src-all@FreeBSD.ORG Wed Jun 17 02:20:27 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 42EC51065694; Wed, 17 Jun 2009 02:20:27 +0000 (UTC) (envelope-from brian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 274BD8FC1C; Wed, 17 Jun 2009 02:20:27 +0000 (UTC) (envelope-from brian@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n5H2KRvu059242; Wed, 17 Jun 2009 02:20:27 GMT (envelope-from brian@svn.freebsd.org) Received: (from brian@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n5H2KRg4059240; Wed, 17 Jun 2009 02:20:27 GMT (envelope-from brian@svn.freebsd.org) Message-Id: <200906170220.n5H2KRg4059240@svn.freebsd.org> From: Brian Somers Date: Wed, 17 Jun 2009 02:20:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r194318 - stable/7/usr.sbin/ppp X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Jun 2009 02:20:28 -0000 Author: brian Date: Wed Jun 17 02:20:26 2009 New Revision: 194318 URL: http://svn.freebsd.org/changeset/base/194318 Log: MFC: r192798: Fix a race that can stall the timer PR: 102747 Submitted by: Sergey Zaharchenko - doublef-ctm at yandex dot ru Modified: stable/7/usr.sbin/ppp/ (props changed) stable/7/usr.sbin/ppp/timer.c Modified: stable/7/usr.sbin/ppp/timer.c ============================================================================== --- stable/7/usr.sbin/ppp/timer.c Wed Jun 17 01:55:42 2009 (r194317) +++ stable/7/usr.sbin/ppp/timer.c Wed Jun 17 02:20:26 2009 (r194318) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1996 - 2001 Brian Somers + * Copyright (c) 1996 - 2001, 2009 Brian Somers * based on work by Toshiharu OHNO * Internet Initiative Japan, Inc (IIJ) * All rights reserved. @@ -94,9 +94,12 @@ timer_Start(struct pppTimer *tp) return; } - /* Adjust our first delta so that it reflects what's really happening */ + /* + * We just need to insert tp in the correct relative place. We don't + * need to adjust TimerList->rest (yet). + */ if (TimerList && getitimer(ITIMER_REAL, &itimer) == 0) - TimerList->rest = RESTVAL(itimer); + ticks = RESTVAL(itimer) - TimerList->rest; pt = NULL; for (t = TimerList; t; t = t->next) { @@ -132,6 +135,7 @@ timer_Start(struct pppTimer *tp) static void StopTimerNoBlock(struct pppTimer *tp) { + struct itimerval itimer; struct pppTimer *t, *pt; /* @@ -156,14 +160,11 @@ StopTimerNoBlock(struct pppTimer *tp) timer_TermService(); /* Terminate Timer Service */ } if (t->next) { - if (!pt) { /* t (tp) was the first in the list */ - struct itimerval itimer; - - if (getitimer(ITIMER_REAL, &itimer) == 0) - t->rest = RESTVAL(itimer); - } - t->next->rest += t->rest; - if (!pt) /* t->next is now the first in the list */ + if (!pt && getitimer(ITIMER_REAL, &itimer) == 0) + t->next->rest += RESTVAL(itimer); /* t (tp) was the first in the list */ + else + t->next->rest += t->rest; + if (!pt && t->next->rest > 0) /* t->next is now the first in the list */ timer_InitService(1); } } else { @@ -235,11 +236,19 @@ timer_Show(int LogLevel, struct prompt * { struct itimerval itimer; struct pppTimer *pt; - u_long rest = 0; + long rest; - /* Adjust our first delta so that it reflects what's really happening */ + /* + * Adjust the base time so that the deltas reflect what's really + * happening. Changing TimerList->rest might cause it to become zero + * (if getitimer() returns a value close to zero), and the + * timer_InitService() call will call setitimer() with zero it_value, + * stopping the itimer... so be careful! + */ if (TimerList && getitimer(ITIMER_REAL, &itimer) == 0) - TimerList->rest = RESTVAL(itimer); + rest = RESTVAL(itimer) - TimerList->rest; + else + rest = 0; #define SECS(val) ((val) / SECTICKS) #define HSECS(val) (((val) % SECTICKS) * 100 / SECTICKS)