Re: Possible bug with nanosleep()?
site_archiver@lists.apple.com Delivered-To: Darwin-kernel@lists.apple.com User-agent: Alpine 1.00 (DEB 882 2007-12-20) Hi Terry and all, 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"); } } int32_t secs = (int32_t) ts.tv_sec; then it hangs forever on OSX. 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 (Darwin-kernel@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-kernel/site_archiver%40lists.a... 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. And if I change both int32_t to long (or __darwin_time_t, the type used in the structure) on this line: 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. This email sent to site_archiver@lists.apple.com
participants (1)
-
Chris Wilson