X-Git-Url: http://ncurses.scripts.mit.edu/?a=blobdiff_plain;f=ncurses%2Ftty%2Flib_twait.c;fp=ncurses%2Flib_twait.c;h=f095c9b53c0c8c5e6c04c7ab56b764d14bb131f5;hb=refs%2Ftags%2Fv5.0;hp=93f24d72488956d2e40cf244a40eb22a1884e974;hpb=661078ddbde3ce0f3b06e95642fbb9b5fef7dca1;p=ncurses.git diff --git a/ncurses/lib_twait.c b/ncurses/tty/lib_twait.c similarity index 54% rename from ncurses/lib_twait.c rename to ncurses/tty/lib_twait.c index 93f24d72..f095c9b5 100644 --- a/ncurses/lib_twait.c +++ b/ncurses/tty/lib_twait.c @@ -40,6 +40,10 @@ ** comments, none of the original code remains - T.Dickey). */ +#ifdef __BEOS__ +#include +#endif + #include #if USE_FUNC_POLL @@ -57,37 +61,34 @@ # endif #endif -#ifdef __BEOS__ -/* BeOS select() only works on sockets. Use the tty hack instead */ -#include -#define select check_select -#endif - -MODULE_ID("$Id: lib_twait.c,v 1.30 1998/02/11 12:14:01 tom Exp $") +MODULE_ID("$Id: lib_twait.c,v 1.34 1999/10/16 21:25:10 tom Exp $") -/* - * We want to define GOOD_SELECT if the last argument of select(2) is - * modified to indicate time left. The code will deal gracefully with - * the other case, this is just an optimization to reduce the number - * of system calls per input event. - * - * In general, expect System-V-like UNIXes to have this behavior and BSD-like - * ones to not have it. Check your manual page. If it doesn't explicitly - * say the last argument is modified, assume it's not. - * - * (We'd really like configure to autodetect this, but writing a proper test - * turns out to be hard.) - */ +static long _nc_gettime(bool first) +{ + long res; #if HAVE_GETTIMEOFDAY -#if (defined(TRACE) && !HAVE_USLEEP) || ! GOOD_SELECT -static void _nc_gettime(struct timeval *tp) -{ - gettimeofday(tp, (struct timezone *)0); - T(("time: %ld.%06ld", (long) tp->tv_sec, (long) tp->tv_usec)); -} -#endif +# define PRECISE_GETTIME 1 + static struct timeval t0; + struct timeval t1; + gettimeofday(&t1, (struct timezone *)0); + if (first) { + t0 = t1; + } + res = (t1.tv_sec - t0.tv_sec) * 1000 + + (t1.tv_usec - t0.tv_usec) / 1000; +#else +# define PRECISE_GETTIME 0 + static time_t t0; + time_t t1 = time((time_t*)0); + if (first) { + t0 = t1; + } + res = (t1 - t0) * 1000; #endif + T(("%s time: %ld msec", first ? "get" : "elapsed", res)); + return res; +} /* * Wait a specified number of milliseconds, returning nonzero if the timer @@ -105,132 +106,128 @@ static void _nc_gettime(struct timeval *tp) int _nc_timed_wait(int mode, int milliseconds, int *timeleft) { int fd; -int count = 0; -long whole_secs = milliseconds / 1000; -long micro_secs = (milliseconds % 1000) * 1000; +int count; -int result = 0; -struct timeval ntimeout; +int result; #if USE_FUNC_POLL struct pollfd fds[2]; +#elif defined(__BEOS__) #elif HAVE_SELECT static fd_set set; #endif -#if !GOOD_SELECT && HAVE_GETTIMEOFDAY -struct timeval starttime, returntime; -long delta; +long starttime, returntime; + + T(("start twait: %d milliseconds, mode: %d", milliseconds, mode)); - _nc_gettime(&starttime); +#if PRECISE_GETTIME +retry: #endif + starttime = _nc_gettime(TRUE); - if (milliseconds >= 0) { - ntimeout.tv_sec = whole_secs; - ntimeout.tv_usec = micro_secs; - } else { - ntimeout.tv_sec = 0; - ntimeout.tv_usec = 0; - } + count = 0; - T(("start twait: %lu.%06lu secs, mode: %d", (long) ntimeout.tv_sec, (long) ntimeout.tv_usec, mode)); +#if USE_FUNC_POLL + if (mode & 1) { + fds[count].fd = SP->_ifd; + fds[count].events = POLLIN; + count++; + } + if ((mode & 2) + && (fd = SP->_mouse_fd) >= 0) { + fds[count].fd = fd; + fds[count].events = POLLIN; + count++; + } + result = poll(fds, count, milliseconds); -#ifdef HIDE_EINTR +#elif defined(__BEOS__) /* - * The do loop tries to make it look like we have restarting signals, - * even if we don't. + * BeOS's select() is declared in socket.h, so the configure script does + * not see it. That's just as well, since that function works only for + * sockets. This (using snooze and ioctl) was distilled from Be's patch + * for ncurses which uses a separate thread to simulate select(). + * + * FIXME: the return values from the ioctl aren't very clear if we get + * interrupted. */ - do { -#endif /* HIDE_EINTR */ -#if !GOOD_SELECT && HAVE_GETTIMEOFDAY - retry: -#endif - count = 0; -#if USE_FUNC_POLL + result = 0; + if (mode & 1) { + bigtime_t d; + bigtime_t useconds = milliseconds * 1000; + int n, howmany; - if (mode & 1) { - fds[count].fd = SP->_ifd; - fds[count].events = POLLIN; - count++; - } - if ((mode & 2) - && (fd = SP->_mouse_fd) >= 0) { - fds[count].fd = fd; - fds[count].events = POLLIN; - count++; + if (useconds == 0) /* we're here to go _through_ the loop */ + useconds = 1; + + for (d = 0; d < useconds; d += 5000) { + n = 0; + howmany = ioctl(0, 'ichr', &n); + if (howmany >= 0 && n > 0) { + result = 1; + break; + } + if (useconds > 1) + snooze(5000); + milliseconds -= 5; } - result = poll(fds, count, milliseconds); + } else if (milliseconds > 0) { + snooze(milliseconds * 1000); + milliseconds = 0; + } #elif HAVE_SELECT - /* - * Some systems modify the fd_set arguments; do this in the - * loop. - */ - FD_ZERO(&set); + /* + * select() modifies the fd_set arguments; do this in the + * loop. + */ + FD_ZERO(&set); - if (mode & 1) { - FD_SET(SP->_ifd, &set); - count = SP->_ifd + 1; - } - if ((mode & 2) - && (fd = SP->_mouse_fd) >= 0) { - FD_SET(fd, &set); - count = max(fd, count) + 1; - } + if (mode & 1) { + FD_SET(SP->_ifd, &set); + count = SP->_ifd + 1; + } + if ((mode & 2) + && (fd = SP->_mouse_fd) >= 0) { + FD_SET(fd, &set); + count = max(fd, count) + 1; + } - errno = 0; - result = select(count, &set, NULL, NULL, milliseconds >= 0 ? &ntimeout : 0); + if (milliseconds >= 0) { + struct timeval ntimeout; + ntimeout.tv_sec = milliseconds / 1000; + ntimeout.tv_usec = (milliseconds % 1000) * 1000; + result = select(count, &set, NULL, NULL, &ntimeout); + } else { + result = select(count, &set, NULL, NULL, NULL); + } #endif -#if !GOOD_SELECT && HAVE_GETTIMEOFDAY - _nc_gettime(&returntime); - - /* The contents of ntimeout aren't guaranteed after return from - * 'select()', so we disregard its contents. Also, note that - * on some systems, tv_sec and tv_usec are unsigned. - */ - ntimeout.tv_sec = whole_secs; - ntimeout.tv_usec = micro_secs; - -#define DELTA(f) (long)ntimeout.f - (long)returntime.f + (long)starttime.f - - delta = DELTA(tv_sec); - if (delta < 0) - delta = 0; - ntimeout.tv_sec = delta; + returntime = _nc_gettime(FALSE); - delta = DELTA(tv_usec); - while (delta < 0 && ntimeout.tv_sec != 0) { - ntimeout.tv_sec--; - delta += 1000000; - } - ntimeout.tv_usec = delta; - if (delta < 0) - ntimeout.tv_sec = ntimeout.tv_usec = 0; + if (milliseconds >= 0) + milliseconds -= (returntime - starttime); - /* - * If the timeout hasn't expired, and we've gotten no data, - * this is probably a system where 'select()' needs to be left - * alone so that it can complete. Make this process sleep, - * then come back for more. - */ - if (result == 0 - && (ntimeout.tv_sec != 0 || ntimeout.tv_usec > 100000)) { - napms(100); - goto retry; - } -#endif -#ifdef HIDE_EINTR - } while (result == -1 && errno == EINTR); +#if PRECISE_GETTIME + /* + * If the timeout hasn't expired, and we've gotten no data, + * this is probably a system where 'select()' needs to be left + * alone so that it can complete. Make this process sleep, + * then come back for more. + */ + if (result == 0 && milliseconds > 100) { + napms(100); + milliseconds -= 100; + goto retry; + } #endif - /* return approximate time left on the ntimeout, in milliseconds */ + /* return approximate time left in milliseconds */ if (timeleft) - *timeleft = (ntimeout.tv_sec * 1000) + (ntimeout.tv_usec / 1000); + *timeleft = milliseconds; - T(("end twait: returned %d (%d), remaining time %lu.%06lu secs (%d msec)", - result, errno, - (long) ntimeout.tv_sec, (long) (ntimeout.tv_usec / 1000), - timeleft ? *timeleft : -1)); + T(("end twait: returned %d (%d), remaining time %d msec", + result, errno, milliseconds)); /* * Both 'poll()' and 'select()' return the number of file descriptors @@ -249,6 +246,8 @@ long delta; count++; } } +#elif defined(__BEOS__) + result = 1; /* redundant, but simple */ #elif HAVE_SELECT if ((mode & 2) && (fd = SP->_mouse_fd) >= 0