[previous] [up] [next]     [contents] [index]
Next: Blocking the Current Thread Up: Threads Previous: Callbacks for Blocked Threads

Sleeping by Embedded MzScheme

Sometimes, MzScheme needs to ``sleep'' -- i.e., block the main thread's execution -- for a certain number of seconds or until external input appears on some file descriptor. Generally, this should block the main event loop of the entire application. However, the way in which sleeping is performed may depend on the embedding application. The global function pointer scheme_sleep can be set by an embedding application to implement a blocking sleep, although MzScheme implements this function for you.

A scheme_sleep function takes two arguments: a float and a void *. The latter is really points to an array of three fd_set (sortof) records (one for read, one for write, and one for exceptions); we explain more about this below. If the float argument is non-zero, then the scheme_sleep function blocks for the specified number of seconds, at most. The scheme_sleep function blocks until there is input on on of the specified file descriptors, indefinitely if the float argument is zero.

The second argument to scheme_sleep is only used for platforms with file descriptions. It is conceptually an array of three fd_set records, but always use scheme_get_fdset to get anything other than the zeroth element of this array, and manipulate each ``fd_set'' with MZ_FD_XXX instead of FD_XXX.

The following function mzsleep is an appropriate scheme_sleep function for most any Unix or Windows application. (This is approximately the built-in sleep used by MzScheme.)

void mzsleep(float v, void *fds)
{
  if (v) {
    sleep(v);
  } else {
    int limit;
    fd_set *rd, *wr, *ex;
    
#ifdef USE_WINSOCK_TCP
    limit = 0;
#else
    limit = getdtablesize();
#endif

    rd = (fd_set *)fds;
    wr = (fd_set *)scheme_get_fdset(fds, 1);
    ex = (fd_set *)scheme_get_fdset(fds, 2);

    select(limit, rd, wr, ex, NULL);
  }
}



PLT