summaryrefslogtreecommitdiff
path: root/lib/util/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/util/util.c')
-rw-r--r--lib/util/util.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/lib/util/util.c b/lib/util/util.c
index 076ddf47fc..296a2a6c68 100644
--- a/lib/util/util.c
+++ b/lib/util/util.c
@@ -165,15 +165,50 @@ _PUBLIC_ bool directory_create_or_exist(const char *dname, uid_t uid,
Sleep for a specified number of milliseconds.
**/
-_PUBLIC_ void msleep(unsigned int t)
+_PUBLIC_ void smb_msleep(unsigned int t)
{
- struct timeval tval;
+#if defined(HAVE_NANOSLEEP)
+ struct timespec ts;
+ int ret;
+
+ ts.tv_sec = t/1000;
+ ts.tv_nsec = 1000000*(t%1000);
+
+ do {
+ errno = 0;
+ ret = nanosleep(&ts, &ts);
+ } while (ret < 0 && errno == EINTR && (ts.tv_sec > 0 || ts.tv_nsec > 0));
+#else
+ unsigned int tdiff=0;
+ struct timeval tval,t1,t2;
+ fd_set fds;
- tval.tv_sec = t/1000;
- tval.tv_usec = 1000*(t%1000);
- /* this should be the real select - do NOT replace
- with sys_select() */
- select(0,NULL,NULL,NULL,&tval);
+ GetTimeOfDay(&t1);
+ t2 = t1;
+
+ while (tdiff < t) {
+ tval.tv_sec = (t-tdiff)/1000;
+ tval.tv_usec = 1000*((t-tdiff)%1000);
+
+ /* Never wait for more than 1 sec. */
+ if (tval.tv_sec > 1) {
+ tval.tv_sec = 1;
+ tval.tv_usec = 0;
+ }
+
+ FD_ZERO(&fds);
+ errno = 0;
+ select(0,&fds,NULL,NULL,&tval);
+
+ GetTimeOfDay(&t2);
+ if (t2.tv_sec < t1.tv_sec) {
+ /* Someone adjusted time... */
+ t1 = t2;
+ }
+
+ tdiff = usec_time_diff(&t1,&t2)/1000;
+ }
+#endif
}
/**