mit-scheme-devel
[Top][All Lists]
Advanced

[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);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]