+ t->pending_asyncs = 1;
+ sleep_object = t->sleep_object;
+ sleep_mutex = t->sleep_mutex;
+ sleep_fd = t->sleep_fd;
+ scm_i_pthread_mutex_unlock (&async_mutex);
+
+ if (sleep_mutex)
+ {
+ /* By now, the thread T might be out of its sleep already, or
+ might even be in the next, unrelated sleep. Interrupting it
+ anyway does no harm, however.
+
+ The important thing to prevent here is to signal sleep_cond
+ before T waits on it. This can not happen since T has
+ sleep_mutex locked while setting t->sleep_mutex and will only
+ unlock it again while waiting on sleep_cond.
+ */
+ scm_i_scm_pthread_mutex_lock (sleep_mutex);
+ scm_i_pthread_cond_signal (&t->sleep_cond);
+ scm_i_pthread_mutex_unlock (sleep_mutex);
+ }
+
+ if (sleep_fd >= 0)
+ {
+ char dummy = 0;
+ /* Likewise, T might already been done with sleeping here, but
+ interrupting it once too often does no harm. T might also
+ not yet have started sleeping, but this is no problem either
+ since the data written to a pipe will not be lost, unlike a
+ condition variable signal.
+ */
+ write (sleep_fd, &dummy, 1);
+ }
+
+ /* This is needed to protect sleep_mutex.
+ */
+ scm_remember_upto_here_1 (sleep_object);
+}
+
+int
+scm_i_setup_sleep (scm_i_thread *t,
+ SCM sleep_object, scm_i_pthread_mutex_t *sleep_mutex,
+ int sleep_fd)
+{
+ int pending;
+
+ scm_i_scm_pthread_mutex_lock (&async_mutex);
+ pending = t->pending_asyncs;
+ if (!pending)
+ {
+ t->sleep_object = sleep_object;
+ t->sleep_mutex = sleep_mutex;
+ t->sleep_fd = sleep_fd;
+ }
+ scm_i_pthread_mutex_unlock (&async_mutex);
+ return pending;
+}
+
+void
+scm_i_reset_sleep (scm_i_thread *t)
+{
+ scm_i_scm_pthread_mutex_lock (&async_mutex);
+ t->sleep_object = SCM_BOOL_F;
+ t->sleep_mutex = NULL;
+ t->sleep_fd = -1;
+ scm_i_pthread_mutex_unlock (&async_mutex);