[comp.sys.hp] Interrupt driven X event loop?

jsd@esl.ESL.COM (Jeff Dalton) (03/14/91)

Short version of question:

  Where are x events queued when using Xm and Xt?  Some events 
  come off the socket, others never make it to the socket but
  are queued.  Where?

Longer version of question:
  
I'm writing an x event loop in Ada which is interrupt
driven so it doesn't need to poll.  The general architecture
is as follows:

-- x event loop
begin
  set_up_socket_for_async_notification; -- via SIGIO
  loop
    if not event_pending
    then
      suspend_until_data_on_socket;
      -- does not block process or poll, but does block
      -- ada task so other ada tasks can run.    			         
    end if;
    get_next_event;
    process_event;
  end loop;
end;


So when a SIGIO is generated the ISR routine does a 
unix select(2) and resumes the ada task which has data 
pending on a socket.  In this case, the x_event_loop.

This works fine as long as ALL events generate a SIGIO
and are placed on the socket.  What seems to be happening
is that some events generated/handled at the Xm or Xt layer
are not raising the SIGIO.  So, for example, if I create
a window with a pushbutton (using Xm and Xt), all the events 
for creating the window raise the SIGIO, but the x_event_loop
will suspend (since no SIGIO was generated) before displaying
the pushbutton.  

If I send a SIGIO to the process (kill(1)), it shows me there
is no data on the socket.  So the events to display the 
button are somewhere and once I do a get_next_event I'll find
them, but they aren't on the socket.  Once I generate an 
event which goes onto the socket (eg. mouse-drag event, etc.)
the button will be displayed.

-Jeff

btw: According to HP Support, this is "out of scope" for them.



-- 
Jeff Dalton, ESL Inc.                    Real programmers can write 
jsd@esl.com                                 Fortran in any language.

chan@hpfcmgw.HP.COM (Chan Benson) (03/19/91)

>      Where are x events queued when using Xm and Xt?  Some events 
>      come off the socket, others never make it to the socket but
>      are queued.  Where?

Xlib has an internal event buffer. All events come through the socket,
but a whole chunk of them may get read at once (even though you've
only asked for one). You need to modify your code so that you don't
block until XPending() returns 0, which means that everything has
been read off the internal queue and there's nothing waiting to be
read from the socket.

Hope that helps. If you need more details, let me know.

			-- Chan Benson
			HP Fort Collins
			

stroyan@hpfcso.FC.HP.COM (Mike Stroyan) (03/19/91)

> -- x event loop
> begin
>   set_up_socket_for_async_notification; -- via SIGIO
>   loop
>     if not event_pending
>     then
>       suspend_until_data_on_socket;
>       -- does not block process or poll, but does block
>       -- ada task so other ada tasks can run.                      
>     end if;
>     get_next_event;
>     process_event;
>   end loop;
> end;

You need to change-
    get_next_event;
    process_event;
to
    while (XPending(display)) {
      get_next_event;
      process_event;
    }

The Xlib library will read large amounts from the socket at one time.
This improves performance by reducing the number of read calls.  It
also means that multiple events may be read in response to one SIGIO.
You may also run into cases where something comes in on the socket that
is not an event.  The XPending test will avoid blocking in "get_next_event"
in that circumstance.

Mike Stroyan, mike_stroyan@fc.hp.com