Re: Possible bug with nanosleep()?
Re: Possible bug with nanosleep()?
- Subject: Re: Possible bug with nanosleep()?
- From: Chris Wilson <email@hidden>
- Date: Tue, 2 Mar 2010 09:26:19 +0100 (CET)
Hi Terry and all,
On Mon, 1 Mar 2010, Terry Lambert wrote:
You need to be looking at tr, not ts, or you need to do the structure
assign immediately after the EINTR, before your trace statements. The
tr contains the remainder time, the ts structure contents are irrelevant
after the nanosleep() call. You're BOX_ macros appear to indicate you
wanted the remainder time.
Sorry, my mistake, my code does that but I edited it somewhat while
writing the email and forgot to update that part of the sample that I
pasted.
For reference, this is the code I have in the application now:
void safe_sleep(int seconds)
{
struct timespec ts;
memset(&ts, 0, sizeof(ts));
ts.tv_sec = seconds;
ts.tv_nsec = 0;
while (nanosleep(&ts, &ts) == -1 && errno == EINTR)
{
// FIXME evil hack for OSX, where ts.tv_sec contains
// a negative number interpreted as unsigned 32-bit
// when nanosleep() returns later than expected.
int32_t secs = (int32_t) ts.tv_sec;
int64_t remain_ns = (secs * 1000000000) + ts.tv_nsec;
if (remain_ns < 0)
{
BOX_WARNING("nanosleep interrupted " <<
((float)(0 - remain_ns) / 1000000000) <<
" secs late");
return;
}
BOX_TRACE("nanosleep interrupted with " <<
(remain_ns / 1000000000) << " secs remaining, "
"sleeping again");
}
}
And if I change both int32_t to long (or __darwin_time_t, the type used
in the structure) on this line:
int32_t secs = (int32_t) ts.tv_sec;
then it hangs forever on OSX.
This looks suspiciously like code one would use to implement a polling loop.
That's generally a mistake.
I don't think it's a polling loop, I just want to damn well be sure that I
sleep for the time requested, regardless of interruption. This function is
used in timing-sensitive unit tests.
I think if you are getting signals often enough for this to be an issue,
you'd be better off passing the same address structure in for both
parameters and specifying SA_RESTART in the flags field.
Actually I originally wrote the code to pass the same structure for both,
and was wondering whether that was allowed (it's not documented as
supported or unsupported) so I wanted to separate the two to make sure
that people wouldn't claim that I was using the function inappropriately
and thus ignore the rest of my message.
Even then, this is probably a bad use of signals, since multiple
signals being sent won't necessarily result in multiple notifications.
I'm not interested at all in signals in this code, I wish they wouldn't
happen, I just want to sleep for the appointed time and nothing else.
Any ideas why I'm seeing (1<<32)-1 in tr.tv_sec after the call, when the
call finishes late? This is the actual problem that I'm having.
Cheers, Chris.
--
_ ___ __ _
/ __/ / ,__(_)_ | Chris Wilson <0000 at qwirx.com> - Cambs UK |
/ (_/ ,\/ _/ /_ \ | Security/C/C++/Java/Perl/SQL/HTML Developer |
\ _/_/_/_//_/___/ | We are GNU-free your mind-and your software |
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden