[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[MIT-Scheme-devel] threads
From: |
Matt Birkholz |
Subject: |
[MIT-Scheme-devel] threads |
Date: |
Thu, 15 May 2014 11:54:41 -0700 |
> From: David Gray <address@hidden>
> Date: Wed, 14 May 2014 11:58:16 +0300
>
> I'm starting a background subprocess and to check the status I
> periodically use:
> (sleep-current-thread 250)
> In Edwin everything is OK but if I run as a batch file or with Emacs
> this function hangs.
> Is there a (load-option) that gets called under Edwin?
Edwin loads many options; the difference is more likely in its top-
level loop. On the console, Edwin blocks in the channel-read
primitive -- old school. On X, it "blocks" by registering editor-
thread as waiting on x-display-descriptor and lets wait-for-io do the
blocking -- next generation. Was Edwin running on the console or an X
window?
Does your hang happen intermittently? If not, can you give us short,
example code that causes the hang? The following, unfortunately,
seems to work fine, printing "Waiting..." 11 times and exiting happy.
$ echo "
(let ((p (start-batch-subprocess \"/bin/bash\" #(\"bash\" \"-c\" \"sleep 5\")
#f)))
(let loop ()
(if (eq? 'EXITED (subprocess-status p))
(display \"Done.\\n\")
(begin
(display \"Waiting...\\n\")
(sleep-current-thread 500)
(loop)))))" | mit-scheme --batch-mode
Can you run the machine under gdb and see where it is hung? Perhaps
in poll, via Prim_test_select_registry?
Years ago I ran into some trouble with <gtk-screen>'s input operations
that caused me to hack the test-select- primitives. They currently
ignore pending interrupts (and subprocess status changes) until
interrupted (again). That's not a problem when the thread-timer is
constantly interrupting, but the timer is NOT running when there is
just one sleeping thread.
If you can rebuild your machine, you might just try the following
patch.
diff --git a/src/microcode/uxio.c b/src/microcode/uxio.c
index df28101..b4f0da9 100644
--- a/src/microcode/uxio.c
+++ b/src/microcode/uxio.c
@@ -596,14 +607,16 @@ OS_test_select_registry (select_registry_t registry, int
blockp)
while (1)
{
int nfds = (safe_poll ((SR_ENTRIES (r)), (SR_N_FDS (r)), blockp));
- if (nfds >= 0)
+ if (nfds > 0)
return (nfds);
- if (errno != EINTR)
+ if (nfds < 0 && errno != EINTR)
error_system_call (errno, syscall_select);
if (OS_process_any_status_change ())
return (SELECT_PROCESS_STATUS_CHANGE);
if (pending_interrupts_p ())
return (SELECT_INTERRUPT);
+ if (nfds == 0) /* and no status-change nor interrupts pending */
+ return (0);
}
}
@@ -618,14 +631,14 @@ OS_test_select_descriptor (int fd, int blockp, unsigned
int mode)
int nfds = (safe_poll (pfds, 1, blockp));
if (nfds > 0)
return (ENCODE_MODE ((pfds [0]) . revents));
- if (nfds == 0)
- return (0);
- if (errno != EINTR)
+ if (nfds < 0 && errno != EINTR)
error_system_call (errno, syscall_select);
if (OS_process_any_status_change ())
return (SELECT_PROCESS_STATUS_CHANGE);
if (pending_interrupts_p ())
return (SELECT_INTERRUPT);
+ if (nfds == 0) /* and no status-change nor interrupts pending */
+ return (0);
}
}
@@ -798,14 +811,16 @@ OS_test_select_registry (select_registry_t registry, int
blockp)
(SR_RREADERS (r)),
(SR_RWRITERS (r)),
blockp));
- if (nfds >= 0)
+ if (nfds > 0)
return (nfds);
- if (errno != EINTR)
+ if (nfds < 0 && errno != EINTR)
error_system_call (errno, syscall_select);
if (OS_process_any_status_change ())
return (SELECT_PROCESS_STATUS_CHANGE);
if (pending_interrupts_p ())
return (SELECT_INTERRUPT);
+ if (nfds == 0) /* and no status-change nor interrupts pending */
+ return (0);
}
#else
error_system_call (ENOSYS, syscall_select);
@@ -835,14 +850,14 @@ OS_test_select_descriptor (int fd, int blockp, unsigned
int mode)
return
(((FD_ISSET (fd, (&readable))) ? SELECT_MODE_READ : 0)
| ((FD_ISSET (fd, (&writeable))) ? SELECT_MODE_WRITE : 0));
- if (nfds == 0)
- return (0);
- if (errno != EINTR)
+ if (nfds < 0 && errno != EINTR)
error_system_call (errno, syscall_select);
if (OS_process_any_status_change ())
return (SELECT_PROCESS_STATUS_CHANGE);
if (pending_interrupts_p ())
return (SELECT_INTERRUPT);
+ if (nfds == 0) /* and no status-change nor interrupts pending */
+ return (0);
}
#else
error_system_call (ENOSYS, syscall_select);