On Thu, Oct 12, 2017 at 08:42:44PM +0000, Mark Lee Smith wrote:
> As the -t option appears to have been available in previous releases so I
> suspect this bug has existed for some time, and effects more than just the
> new autoactions, although what it might effect I can't say.
> 
> I hope that I've managed to provide enough information to confirm that a
> bug exists and gone some way to helping isolate it.
> 
> All the best,
> 
> Mark

Hi Mark,

I just realized that I've always used apmd with -t 10 and thus never had
any issue with this.  I've did a bit of testing now and as far as I can
tell, apmtimeout is sometimes incorrect as the loop doesn't iterate
every second.

The patch below uses a time() timestamp instead and compares it to the
time when last iteration occured.  This may not be the best solutions
considering suspending/resuming and the clock might be off. The quick
fix for this is to simply reset the timestamp if things seems off and
the worst-case scenario is that we poll an extra time.


Jesper Wallin


Index: apmd.c
===================================================================
RCS file: /cvs/src/usr.sbin/apmd/apmd.c,v
retrieving revision 1.80
diff -u -p -r1.80 apmd.c
--- apmd.c      28 Aug 2017 16:16:58 -0000      1.80
+++ apmd.c      13 Oct 2017 09:01:31 -0000
@@ -358,7 +358,7 @@ main(int argc, char *argv[])
        int noacsleep = 0;
        struct timespec ts = {TIMO, 0}, sts = {0, 0};
        struct apm_power_info pinfo;
-       time_t apmtimeout = 0;
+       time_t tc, tn;
        const char *sockname = sockfile;
        const char *errstr;
        int kq, nchanges;
@@ -482,17 +482,18 @@ main(int argc, char *argv[])
        if (sysctl(ncpu_mib, 2, &ncpu, &ncpu_sz, NULL, 0) < 0)
                error("cannot read hw.ncpu", NULL);
 
+       tc = time(NULL);
        for (;;) {
                int rv;
 
                sts = ts;
+               tn = time(NULL);
 
-               apmtimeout += 1;
                if ((rv = kevent(kq, NULL, 0, ev, 1, &sts)) < 0)
                        break;
 
-               if (apmtimeout >= ts.tv_sec) {
-                       apmtimeout = 0;
+               if (tn-tc >= ts.tv_sec || tn < tc) {
+                       tc = time(NULL);
 
                        /* wakeup for timeout: take status */
                        powerbak = power_status(ctl_fd, 0, &pinfo);

Reply via email to