Asynchronous events in Eiffel 
Author Message
 Asynchronous events in Eiffel

How would one preferably handle asynchronous events in Eiffel? By this,
I mean something like catching a UNIX signal. I find it odd that there
are a number of things that C and Tcl can handle safely that Eiffel and
Java cannot, like a routine that does an accept() on a socket, but times
out after 30 seconds if nobody connects to the socket in that time.

My initial thought would be to have a SIGNAL class that allows ignoring
or catching particular signals, or waiting for them to occur. Ignored
signals would be ignored, caught signals would increment a counter each
time they're caught (allowing code to synchronously handle the event by
polling for signal occurances), and waited-for signals would block a
thread until they occur (most useful in multithreaded environments, of
course). The problem of throwing an exception when a signal occurs is
that it makes it virtually impossible to avoid race conditions (even
assuming you catch the exception) and calling an arbitrary callback
routine is clearly going to have trouble with being invoked in the
middle of some other routine at an arbitrary point.

As a concrete example: Write a server that listens on socket 2000. Each
time it gets a connection, it reads one line, and writes it back to that
connection, then closes the connection (i.e., it echos one line). I want
to close the listening connection as soon as I get a HUP signal or if
one of the connections gives me the string "QUIT" and I echo that back.
However, I don't ever want to abort connections that have already been
accepted; I just want to stop listening for new ones at some point. I've
been unable to make this happen in Java (altho it's pretty easy in C and
Tcl), and I don't think I can do it with ISE Eiffel either.

It would also be nice to know if it's possible to (say) run a server
that would take commands over a socket to maintain a hash table or
linked list or whatever, and dump the data structure to a file
periodically (or froma signal) in case of crashes or whatever. If the
signal occurs during a data structure update, how is one sure that the
entire data structure hasn't been corrupted?

Thoughts, anyone?

--
Darren New / Senior Software Architect / First Virtual Holdings Inc
Fingerprint: 61 7D AF 9E 00 CC C2 ED / D8 4C D7 AA E4 C2 A0 73
The Three Scrooges: "Repent, Jacob Marley!" >poink!< Ow! "Woo-woo-woo!"



Fri, 18 May 2001 03:00:00 GMT  
 Asynchronous events in Eiffel

Quote:

> As a concrete example: Write a server that listens on socket 2000. Each
> time it gets a connection, it reads one line, and writes it back to that
> connection, then closes the connection (i.e., it echos one line). I want
> to close the listening connection as soon as I get a HUP signal or if
> one of the connections gives me the string "QUIT" and I echo that back.
> However, I don't ever want to abort connections that have already been
> accepted; I just want to stop listening for new ones at some point. I've
> been unable to make this happen in Java (altho it's pretty easy in C and
> Tcl), and I don't think I can do it with ISE Eiffel either.

> It would also be nice to know if it's possible to (say) run a server
> that would take commands over a socket to maintain a hash table or
> linked list or whatever, and dump the data structure to a file
> periodically (or froma signal) in case of crashes or whatever. If the
> signal occurs during a data structure update, how is one sure that the
> entire data structure hasn't been corrupted?

> Thoughts, anyone?

Have I missed something?  Isn't this just a standard "critical section"
problem?  All data structure update code is protected by a "lock"
(i.e., a mutex, or a Win32 CRITICAL_SECTION).

Ken Carpenter



Sat, 19 May 2001 03:00:00 GMT  
 Asynchronous events in Eiffel

Quote:

> How would one preferably handle asynchronous events in Eiffel? By this,
> I mean something like catching a UNIX signal. I find it odd that there
> are a number of things that C and Tcl can handle safely that Eiffel and
> Java cannot, like a routine that does an accept() on a socket, but times
> out after 30 seconds if nobody connects to the socket in that time.

First, to offer a solution: Use select() with a timeout of 30 seconds,
and avoid asynchronous I/O entirely. (Note also that some operating
systems do not implement asynchronous I/O for all file types.)

Second, I have to agree. The concept of external OS signals raising
exceptions is one of the few outright braindead ideas in Eiffel. There
simply is no way to handle them in a sane fashion if you do this.
Unfortunately, even SmallEiffel has adopted this policy as of late.

Quote:
> My initial thought would be to have a SIGNAL class that allows ignoring
> or catching particular signals, or waiting for them to occur. Ignored
> signals would be ignored, caught signals would increment a counter each
> time they're caught (allowing code to synchronously handle the event by
> polling for signal occurances), and waited-for signals would block a
> thread until they occur (most useful in multithreaded environments, of
> course).

That's basically how you'd normally do it in a concurrent environment.
Unfortunately, there is no concurrency standard for Eiffel (there's
EiffelThreads, but that's ISE only and not a standard). On the other
hand, we have so far been spared the usual primitive approaches to
threading that require you to do locking, monitors, etc. manually.

Quote:
> The problem of throwing an exception when a signal occurs is
> that it makes it virtually impossible to avoid race conditions (even
> assuming you catch the exception) and calling an arbitrary callback
> routine is clearly going to have trouble with being invoked in the
> middle of some other routine at an arbitrary point.

It's worse. Imagine that you're in the process of iterating over some
data structure when a SIGCHLD or SIGIO occurs. No matter what you do,
you'll most likely end up with a lot of s{*filter*}data, if exception
handling is the only way to process a signal.

[...]

                                Reimer Behrends



Sat, 19 May 2001 03:00:00 GMT  
 Asynchronous events in Eiffel

Reimer Behrends a crit dans le message ...

Quote:
>It's worse. Imagine that you're in the process of iterating over some
>data structure when a SIGCHLD or SIGIO occurs. No matter what you do,
>you'll most likely end up with a lot of s{*filter*}data, if exception
>handling is the only way to process a signal.

Wouldn't a try/finally instruction help in this case as with exceptions in
general ?

Regards
Jocelyn



Sat, 19 May 2001 03:00:00 GMT  
 Asynchronous events in Eiffel

Quote:

> Reimer Behrends a crit dans le message ...
> >It's worse. Imagine that you're in the process of iterating over some
> >data structure when a SIGCHLD or SIGIO occurs. No matter what you do,
> >you'll most likely end up with a lot of s{*filter*}data, if exception
> >handling is the only way to process a signal.
> Wouldn't a try/finally instruction help in this case as with exceptions in
> general ?

No.

The problem is that an external signal can occur at any time, in any
place (as opposed to signals being raised by floating point errors,
accessing Void references, etc.).

Consider the following code:

        from
          it := list.iterator
          it.start
        until it.outside loop
          it.item.modify_in_some_way
          -- signal occurs here at some point of the iteration
          it.forth
        end

You end up with a half-processed list.

How would you be able to handle this? IMNSHO it's impossible.

                                Reimer Behrends



Sat, 19 May 2001 03:00:00 GMT  
 Asynchronous events in Eiffel

Quote:

> How would one preferably handle asynchronous events in Eiffel? By this,
> I mean something like catching a UNIX signal. I find it odd that there
> are a number of things that C and Tcl can handle safely that Eiffel and
> Java cannot, like a routine that does an accept() on a socket, but times
> out after 30 seconds if nobody connects to the socket in that time.

I'm not responding to the UNIX signal part of this thread, but ...

I've just read the EiffelNet documentation on the weekend (although
haven't used it yet). I'm pretty sure (if I comprehended to doco's
correctly) ISE's EiffelNet can do this. Have you looked at this library?

Loryn Jenkins



Sat, 19 May 2001 03:00:00 GMT  
 Asynchronous events in Eiffel

Reimer Behrends a crit dans le message ...

Quote:

>> Reimer Behrends a crit dans le message ...
>> >It's worse. Imagine that you're in the process of iterating over some
>> >data structure when a SIGCHLD or SIGIO occurs. No matter what you do,
>> >you'll most likely end up with a lot of s{*filter*}data, if exception
>> >handling is the only way to process a signal.
>> Wouldn't a try/finally instruction help in this case as with exceptions
in
>> general ?

>No.

>The problem is that an external signal can occur at any time, in any
>place (as opposed to signals being raised by floating point errors,
>accessing Void references, etc.).

>Consider the following code:

> from
>   it := list.iterator
>   it.start
> until it.outside loop
>   it.item.modify_in_some_way
>   -- signal occurs here at some point of the iteration
>   it.forth
> end

>You end up with a half-processed list.

>How would you be able to handle this? IMNSHO it's impossible.

> Reimer Behrends

I was thinking of resource allocations but in your case you need a
transactional engine.

Regards
Jocelyn



Sat, 19 May 2001 03:00:00 GMT  
 Asynchronous events in Eiffel

[...]

Quote:

> The problem is that an external signal can occur at any time, in any
> place (as opposed to signals being raised by floating point errors,
> accessing Void references, etc.).

> Consider the following code:

>         from
>           it := list.iterator
>           it.start
>         until it.outside loop
>           it.item.modify_in_some_way
>           -- signal occurs here at some point of the iteration
>           it.forth
>         end

> You end up with a half-processed list.

> How would you be able to handle this? IMNSHO it's impossible.

It's not impossible. When a signal occurs a handler is called,
after the handler is done the interupted process is resumed
at the point at which is was suspended.

The problems may arise because data structures that can be
modified by the handler can mess up the main process. In
particular you have to worry about the Eiffel runtime
if the signal handler is written in Eiffel.

A typical design would have the signal handler do the minimal
amount of stuff (like queue important info somewhere) and then
return and make sure that the main process is running. Then
the main process can remove the signal info from that same queue
and do whatever processing needs doing.

The important thing is to block other signals while the
"signal info" queue is being modified.

...richie

http://www.netlabs.net/~richieb



Sat, 19 May 2001 03:00:00 GMT  
 Asynchronous events in Eiffel
[Exception-raising signal inside a loop that transforms a list.]

Quote:
> > You end up with a half-processed list.

> > How would you be able to handle this? IMNSHO it's impossible.

> It's not impossible. When a signal occurs a handler is called,
> after the handler is done the interupted process is resumed
> at the point at which is was suspended.

Umm. I was specifically addressing the case of external signals raising
exceptions. If you set up a separate handler, that's fine with me,
because then you don't raise an exception.

Unfortunately, this is contrary to what ELKS, ETL, OOSC I & II suggest.

Quote:
> The problems may arise because data structures that can be
> modified by the handler can mess up the main process. In
> particular you have to worry about the Eiffel runtime
> if the signal handler is written in Eiffel.

Yes. As I said before, in this case it would become a concurrency issue.
Would.

[...]

                                Reimer Behrends



Sat, 19 May 2001 03:00:00 GMT  
 Asynchronous events in Eiffel
[Signals that raise exceptions.]

Quote:
> I was thinking of resource allocations but in your case you need a
> transactional engine.

Won't do. The behaviour of programs that can be interrupted at arbitrary
points is simply unpredictable. You'd have to safeguard every piece of
code that you write, than you have to safeguard the safeguards, then you
have to ...

And if you have transactions, then signals can occur within
transactions. Signals can occur even within a rescue clause. They are
basically OS level abstractions for hardware/software interrupts. As a
result, atomicity with respect to them is non-existent for all practical
purposes (beyond the machine instruction level, and sometimes not even
that).

                                Reimer Behrends



Sat, 19 May 2001 03:00:00 GMT  
 Asynchronous events in Eiffel

[...]

Quote:

> Umm. I was specifically addressing the case of external signals raising
> exceptions. If you set up a separate handler, that's fine with me,
> because then you don't raise an exception.

You are right. If an exception is raised there are problems.

Quote:

> Unfortunately, this is contrary to what ELKS, ETL, OOSC I & II suggest.

It's not clear that's what they suggest. OOSC II at least,
gives an example of doing exceptions with signal/setjmp/longjmp
which is the same as rescue/retry. But we're talking
about concurrency. In SCOOP again exceptions are used
to interrupt threads, but not specifically as responses
to signals.

But I think you are right, there is a middle level missing.
Today it would be very hard to write signal handlers
(Unix style) in Eiffel, unless we could verify that the
runtime will behave properly.

...richie

http://www.netlabs.net/~richieb



Sat, 19 May 2001 03:00:00 GMT  
 Asynchronous events in Eiffel

Quote:

> I've just read the EiffelNet documentation on the weekend (although
> haven't used it yet). I'm pretty sure (if I comprehended to doco's
> correctly) ISE's EiffelNet can do this. Have you looked at this library?

Well, the EiffelNet documentation on the web is a bit... scant. No short
forms, for example. And it costs as much as the compiler does, for
personal use. I'm not sure I want to go there yet.

--
Darren New / Senior Software Architect / First Virtual Holdings Inc
Fingerprint: 61 7D AF 9E 00 CC C2 ED / D8 4C D7 AA E4 C2 A0 73
The Three Scrooges: "Repent, Jacob Marley!" >poink!< Ow! "Woo-woo-woo!"



Sat, 19 May 2001 03:00:00 GMT  
 Asynchronous events in Eiffel

Quote:


> > I've just read the EiffelNet documentation on the weekend (although
> > haven't used it yet). I'm pretty sure (if I comprehended to doco's
> > correctly) ISE's EiffelNet can do this. Have you looked at this library?

> Well, the EiffelNet documentation on the web is a bit... scant. No short
> forms, for example. And it costs as much as the compiler does, for
> personal use. I'm not sure I want to go there yet.

Take a look at my free socket libs and Emu Web server:

        http://www.netlabs.net/~richieb/emu

for some examples of using "select" etc.

...richie



Sat, 19 May 2001 03:00:00 GMT  
 
 [ 13 post ] 

 Relevant Pages 

1. Tcl Event Loop vs TK Event Loop issues with Asynchronous Events

2. Asynchronous Communication Events

3. Asynchronous Event Handlers

4. Asynchronous Event Handlers (Tcl_AsyncCreate) Usage with multiple threads

5. how to block asynchronous events?

6. Asynchronous Events in Tcl

7. asynchronous file events

8. Catching resize events in ISE Eiffel Vision?

9. Smalltalk/MVC Vs Eiffel/Event-Context Model

10. Discrete Event Simulation with EIFFEL

11. Receiving Apple Events in a RB app (HandleAppleEvent event)

 

 
Powered by phpBB® Forum Software