emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: More info on sporadic OS/X crash


From: YAMAMOTO Mitsuharu
Subject: Re: More info on sporadic OS/X crash
Date: Sat, 01 May 2004 20:32:49 +0900
User-agent: Wanderlust/2.10.1 (Watching The Wheels) SEMI/1.14.5 (Awara-Onsen) FLIM/1.14.5 (Demachiyanagi) APEL/10.6 Emacs/21.3.50 (sparc-sun-solaris2.8) MULE/5.0 (SAKAKI)

>>>>> On 27 Apr 2004 17:24:36 +0200, Piet van Oostrum <address@hidden> said:

> However now I have occasional hangs in select(), always when using
> gnus.  It could be a server that is not responding, but I am not
> sure. 

I encountered the following situation (though I'm not sure whether it
is related to the above one):

   1. select (actually, sys_select in mac.c) is called from
      wait_reading_process_input.
   2. Interrupt by SIGALRM occurs while ReceiveNextEvent in sys_select
      is being processed.
   3. ReceiveNextEvent is called from XTread_socket again.
   4. Emacs hangs.

So at least ReceiveNextEvent in sys_select must be enclosed with
BLOCK_INPUT/UNBLOCK_INPUT.

Below is the sys_select function currently I'm using.  Besides the
above issue, I also modified the calculation of the remaining time for
timeout and added a special handling for the common case where there
are no subprocesses to be monitored.

                                     YAMAMOTO Mitsuharu
                                address@hidden

#include "blockinput.h"
int
sys_select (n, rfds, wfds, efds, timeout)
  int n;
  SELECT_TYPE *rfds;
  SELECT_TYPE *wfds;
  SELECT_TYPE *efds;
  struct timeval *timeout;
{
  OSErr err;
  EMACS_TIME end_time, now, remaining_time;

  if (inhibit_window_system || noninteractive
      || rfds == NULL || !FD_ISSET (0, rfds))
    return select(n, rfds, wfds, efds, timeout);

  if (wfds == NULL && efds == NULL)
    {
      int i;

      for (i = 1; i < n; i++)
        if (FD_ISSET (i, rfds))
          break;
      if (i == n)
        {
          EventTimeout timeout_sec =
            (timeout
             ? (EMACS_SECS (*timeout) + EMACS_USECS (*timeout) / 1000000.0)
             : kEventDurationForever);

          BLOCK_INPUT;
          err = ReceiveNextEvent (0, NULL, timeout_sec, false, NULL);
          UNBLOCK_INPUT;
          if (err == noErr)
            {
              FD_ZERO (rfds);
              FD_SET (0, rfds);
              return 1;
            }
          else
            return 0;
        }
    }

  if (timeout)
    {
      remaining_time = *timeout;
      EMACS_GET_TIME (now);
      EMACS_ADD_TIME (end_time, now, remaining_time);
    }

  FD_CLR (0, rfds);
  do
    {
      EMACS_TIME select_timeout;
      SELECT_TYPE orfds = *rfds;
      int r;

      EMACS_SET_SECS_USECS (select_timeout, 0, 20000);

      if (timeout && EMACS_TIME_LT (remaining_time, select_timeout))
        select_timeout = remaining_time;

      r = select (n, &orfds, wfds, efds, &select_timeout);
      BLOCK_INPUT;
      err = ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, NULL);
      UNBLOCK_INPUT;
      if (r > 0)
        {
          *rfds = orfds;
          if (err == noErr)
            {
              FD_SET (0, rfds);
              r++;
            }
          return r;
        }
      else if (err == noErr)
        {
          FD_ZERO (rfds);
          FD_SET (0, rfds);
          return 1;
        }

      if (timeout)
        {
          EMACS_GET_TIME (now);
          EMACS_SUB_TIME (remaining_time, end_time, now);
        }
    }
  while (!timeout || EMACS_TIME_LT (now, end_time));

  return 0;
}




reply via email to

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