public inbox for java@gcc.gnu.org
 help / color / mirror / Atom feed
* RE: Thread.interrupt()
@ 2000-03-14  6:00 Miles Sabin
  2000-03-14  7:36 ` Thread.interrupt() Jeff Sturm
  2000-04-01  0:00 ` Thread.interrupt() Miles Sabin
  0 siblings, 2 replies; 51+ messages in thread
From: Miles Sabin @ 2000-03-14  6:00 UTC (permalink / raw)
  To: java-discuss

Jeff Sturm wrote,
> IOW, Sun crippled their API because Win32 doesn't handle 
> interruptable I/O portably.  Not a good policy.
>
> Since Java doesn't support read() with timeouts either, it is 
> easy to create a "stuck" thread that can never die.

The following posting of Doug Lea's on this topic from a while 
back on the advanced-java list is the best response to your
complaint ...

Doug Lea wrote,
> I think the consensus is that Interruptible I/O was a
> reasonable-looking notion that turned out to be a bad idea in
> practice. In fact, I hope it becomes deprecated before it is 
> fully implemented. (Currently, it is very incompletely 
> implemented, at least on Solaris and Win platforms.) The 
> fundamental problem is that there is rarely a reasonable 
> continuation action that can be taken if low-level I/O 
> interrupts.  Most Java programs use buffered or translated 
> I/O classes, which in turn rely on lower-level I/O classes. 
> But there is hardly ever a way for them to roll back or
> forward under a lower level exception. So the only recourse 
> is to abort.
>
> Given this (see http://gee.cs.oswego.edu/dl/cpj/cancel.html ), 
> usually the best way to implement cancellation in I/O is just 
> resource revocation -- asynchronously forcibly closing the 
> stream that the thread is operating on. This results in a 
> generic I/O exception, which can then be used to shut down a 
> thread. This works well (at least on Solaris 1.2. I don't 
> know about other platforms). To play it safe, and force 
> termination whether the thread is actually doing any I/O, you
> should normally do both stream.close() and Thread.interrupt
> ().

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14  6:00 Thread.interrupt() Miles Sabin
@ 2000-03-14  7:36 ` Jeff Sturm
  2000-03-14 10:58   ` Thread.interrupt() Tom Tromey
  2000-04-01  0:00   ` Thread.interrupt() Jeff Sturm
  2000-04-01  0:00 ` Thread.interrupt() Miles Sabin
  1 sibling, 2 replies; 51+ messages in thread
From: Jeff Sturm @ 2000-03-14  7:36 UTC (permalink / raw)
  To: Miles Sabin; +Cc: java-discuss

Miles Sabin wrote:
> The following posting of Doug Lea's on this topic from a while
> back on the advanced-java list is the best response to your
> complaint ...
> 
> Doug Lea wrote,
[...]
> > Given this (see http://gee.cs.oswego.edu/dl/cpj/cancel.html ),
> > usually the best way to implement cancellation in I/O is just
> > resource revocation -- asynchronously forcibly closing the
> > stream that the thread is operating on. This results in a
> > generic I/O exception, which can then be used to shut down a
> > thread. This works well (at least on Solaris 1.2. I don't
> > know about other platforms). To play it safe, and force
> > termination whether the thread is actually doing any I/O, you
> > should normally do both stream.close() and Thread.interrupt
> > ().

That sounds like trading one set of underspecified behavior for
another.  I haven't tested myself this on any range of platforms.

Some stream classes are virtual, like PipedReader.  It blocks on
object.wait().   Waking it up with an interrupt would be easy enough. 
It can be made to respond to a close() as well.

Currently in libgcj, we have:

                // Note that JCL doesn't say this is the right thing
                // to do.  Still, it feels right, and we must deal
                // with an interrupt somehow.
                try
                  {
                    lock.wait();
                  }
                catch (InterruptedException e)
                  {
                    InterruptedIOException io
                      = new InterruptedIOException (e.getMessage());
                    io.bytesTransferred = count - toCopy;
                    throw io;
                  }
              }

in PipedReader.read().  The close() method is simply:

  public void close () throws IOException
  {
    closed = true;
  }

So the reader thread will remain blocked after close.  We could modify
close() to call lock.notifyAll(), and check the closed flag in read(). 
So at least for this class, Doug Lea's suggestion could probably be made
to work.  I don't know how easy it would be to implement throughout
java.io however.  Thoughts?

-- 
Jeff Sturm
jsturm@sigma6.com

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14  7:36 ` Thread.interrupt() Jeff Sturm
@ 2000-03-14 10:58   ` Tom Tromey
  2000-04-01  0:00     ` Thread.interrupt() Tom Tromey
  2000-04-01  0:00   ` Thread.interrupt() Jeff Sturm
  1 sibling, 1 reply; 51+ messages in thread
From: Tom Tromey @ 2000-03-14 10:58 UTC (permalink / raw)
  To: Jeff Sturm; +Cc: Miles Sabin, java-discuss

Jeff> So the reader thread will remain blocked after close.  We could
Jeff> modify close() to call lock.notifyAll(), and check the closed
Jeff> flag in read().  So at least for this class, Doug Lea's
Jeff> suggestion could probably be made to work.  I don't know how
Jeff> easy it would be to implement throughout java.io however.
Jeff> Thoughts?

I agree with Hans that resource revocation is an ugly way to go.  It
only works if you have a lot of knowledge of what the other thread is
doing.

Still, I think this ought to work -- that is, you found a bug in the
pipe classes.  Could you send a PR and/or patch?

Tom

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14  7:36 ` Thread.interrupt() Jeff Sturm
  2000-03-14 10:58   ` Thread.interrupt() Tom Tromey
@ 2000-04-01  0:00   ` Jeff Sturm
  1 sibling, 0 replies; 51+ messages in thread
From: Jeff Sturm @ 2000-04-01  0:00 UTC (permalink / raw)
  To: Miles Sabin; +Cc: java-discuss

Miles Sabin wrote:
> The following posting of Doug Lea's on this topic from a while
> back on the advanced-java list is the best response to your
> complaint ...
> 
> Doug Lea wrote,
[...]
> > Given this (see http://gee.cs.oswego.edu/dl/cpj/cancel.html ),
> > usually the best way to implement cancellation in I/O is just
> > resource revocation -- asynchronously forcibly closing the
> > stream that the thread is operating on. This results in a
> > generic I/O exception, which can then be used to shut down a
> > thread. This works well (at least on Solaris 1.2. I don't
> > know about other platforms). To play it safe, and force
> > termination whether the thread is actually doing any I/O, you
> > should normally do both stream.close() and Thread.interrupt
> > ().

That sounds like trading one set of underspecified behavior for
another.  I haven't tested myself this on any range of platforms.

Some stream classes are virtual, like PipedReader.  It blocks on
object.wait().   Waking it up with an interrupt would be easy enough. 
It can be made to respond to a close() as well.

Currently in libgcj, we have:

                // Note that JCL doesn't say this is the right thing
                // to do.  Still, it feels right, and we must deal
                // with an interrupt somehow.
                try
                  {
                    lock.wait();
                  }
                catch (InterruptedException e)
                  {
                    InterruptedIOException io
                      = new InterruptedIOException (e.getMessage());
                    io.bytesTransferred = count - toCopy;
                    throw io;
                  }
              }

in PipedReader.read().  The close() method is simply:

  public void close () throws IOException
  {
    closed = true;
  }

So the reader thread will remain blocked after close.  We could modify
close() to call lock.notifyAll(), and check the closed flag in read(). 
So at least for this class, Doug Lea's suggestion could probably be made
to work.  I don't know how easy it would be to implement throughout
java.io however.  Thoughts?

-- 
Jeff Sturm
jsturm@sigma6.com

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
  2000-03-14  6:00 Thread.interrupt() Miles Sabin
  2000-03-14  7:36 ` Thread.interrupt() Jeff Sturm
@ 2000-04-01  0:00 ` Miles Sabin
  1 sibling, 0 replies; 51+ messages in thread
From: Miles Sabin @ 2000-04-01  0:00 UTC (permalink / raw)
  To: java-discuss

Jeff Sturm wrote,
> IOW, Sun crippled their API because Win32 doesn't handle 
> interruptable I/O portably.  Not a good policy.
>
> Since Java doesn't support read() with timeouts either, it is 
> easy to create a "stuck" thread that can never die.

The following posting of Doug Lea's on this topic from a while 
back on the advanced-java list is the best response to your
complaint ...

Doug Lea wrote,
> I think the consensus is that Interruptible I/O was a
> reasonable-looking notion that turned out to be a bad idea in
> practice. In fact, I hope it becomes deprecated before it is 
> fully implemented. (Currently, it is very incompletely 
> implemented, at least on Solaris and Win platforms.) The 
> fundamental problem is that there is rarely a reasonable 
> continuation action that can be taken if low-level I/O 
> interrupts.  Most Java programs use buffered or translated 
> I/O classes, which in turn rely on lower-level I/O classes. 
> But there is hardly ever a way for them to roll back or
> forward under a lower level exception. So the only recourse 
> is to abort.
>
> Given this (see http://gee.cs.oswego.edu/dl/cpj/cancel.html ), 
> usually the best way to implement cancellation in I/O is just 
> resource revocation -- asynchronously forcibly closing the 
> stream that the thread is operating on. This results in a 
> generic I/O exception, which can then be used to shut down a 
> thread. This works well (at least on Solaris 1.2. I don't 
> know about other platforms). To play it safe, and force 
> termination whether the thread is actually doing any I/O, you
> should normally do both stream.close() and Thread.interrupt
> ().

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14 10:58   ` Thread.interrupt() Tom Tromey
@ 2000-04-01  0:00     ` Tom Tromey
  0 siblings, 0 replies; 51+ messages in thread
From: Tom Tromey @ 2000-04-01  0:00 UTC (permalink / raw)
  To: Jeff Sturm; +Cc: Miles Sabin, java-discuss

Jeff> So the reader thread will remain blocked after close.  We could
Jeff> modify close() to call lock.notifyAll(), and check the closed
Jeff> flag in read().  So at least for this class, Doug Lea's
Jeff> suggestion could probably be made to work.  I don't know how
Jeff> easy it would be to implement throughout java.io however.
Jeff> Thoughts?

I agree with Hans that resource revocation is an ugly way to go.  It
only works if you have a lot of knowledge of what the other thread is
doing.

Still, I think this ought to work -- that is, you found a bug in the
pipe classes.  Could you send a PR and/or patch?

Tom

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Thread.interrupt()
@ 2000-04-01  0:00 Bryce McKinlay
  2000-03-13 13:33 ` Thread.interrupt() Bryce McKinlay
  0 siblings, 1 reply; 51+ messages in thread
From: Bryce McKinlay @ 2000-04-01  0:00 UTC (permalink / raw)
  To: java-discuss

Is there any online documentation where the semantics of
thread.interrupt() are fairly precisely specified? It isn't mentioned in
either the JLS or JVM spec, and the API documentation is a little bit...
vague.

regards

  [ bryce ]


^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
  2000-03-14  7:47 Thread.interrupt() Miles Sabin
@ 2000-04-01  0:00 ` Miles Sabin
  0 siblings, 0 replies; 51+ messages in thread
From: Miles Sabin @ 2000-04-01  0:00 UTC (permalink / raw)
  To: java-discuss

Jeff Sturm wrote,
> [snip: resource revocation as an alternative to interrupt()]
> That sounds like trading one set of underspecified behavior 
> for another.  I haven't tested myself this on any range of 
> platforms.

Perhaps, yes. However, I would expect any robust implementation
of a stream class to respond in the Right Way to closure.

> Some stream classes are virtual, like PipedReader.  It blocks 
> on object.wait().   Waking it up with an interrupt would be 
> easy enough. It can be made to respond to a close() as well.

It is in Sun's implementation (all the recent one's anyhow).
The alternative would be to leave either or both of the
producer/consumer threads permanently blocked ... if that
happened I'd call it a bug, independently of any issues around
interruption.

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
  2000-03-15 11:38 Thread.interrupt() Boehm, Hans
@ 2000-04-01  0:00 ` Boehm, Hans
  0 siblings, 0 replies; 51+ messages in thread
From: Boehm, Hans @ 2000-04-01  0:00 UTC (permalink / raw)
  To: 'Miles Sabin', java-discuss

I agree that you can invent a protocol that will make it possible to
interrupt a thread blocked on I/O by closing a file descriptor (assuming
that closing a file descriptor actually terminates a read).  The crucial
problem with this is that at least every class in the system that performs
blocking I/O has to play by these rules.  In most cases, you  won't have
control over all of them.  And those implemented by others won't play by
your rules.  For example, I'd be surprised if something like
java.net.URLConnection gave access to all file descriptors it might wait on,
e.g. for name lookups.

Thread.interrupt() was intended to provide a general solution to this
problem, effectively by standardizing the protocol (and making it a bit more
general in the process). 

Hans

-----Original Message-----
From: Miles Sabin [ mailto:msabin@cromwellmedia.co.uk ]
Sent: Wednesday, March 15, 2000 5:51 AM
To: java-discuss@sourceware.cygnus.com
Subject: RE: Thread.interrupt()


Boehm, Hans wrote,
> Thread A decides it wants to cancel thread B.  How can it 
> close the file descriptor, which is located in a local 
> variable 28 frames down in B's stack?  Even if B cooperated,
> and put the file descriptor in some public place, there's no 
> obvious place to put it. It can't put it in a fixed global 
> place, since C and D might overwrite it.

I don't see this as a problem specific to interruptable IO or
even concurrency. Similar issues might arise in, for example, 
(syntactic) error handling/recovery in a recursive descent 
parser, or any number of other scenarios where the stack is
used to encode an objects state.

In fact, it looks like a straightforward software design issue 
to me. Effectively what you're saying is that cancellation is a 
first class aspect of the behaviour associated with thread B. 
That being so it should be exposed at the interface level and
then implemented in whatever the appropriate way is. For a 
simple example: B's Runnable instance might have a register() 
method to allow the 28-frame-down FD to be associated with the 
the state of thread B as a whole; and a cancel() method 
accessible to A which closes it.

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-13 13:33 ` Thread.interrupt() Bryce McKinlay
  2000-03-14  2:24   ` Thread.interrupt() Kresten Krab Thorup
@ 2000-04-01  0:00   ` Bryce McKinlay
  1 sibling, 0 replies; 51+ messages in thread
From: Bryce McKinlay @ 2000-04-01  0:00 UTC (permalink / raw)
  To: java-discuss

Bryce McKinlay wrote:

> Is there any online documentation where the semantics of
> thread.interrupt() are fairly precisely specified? It isn't mentioned in
> either the JLS or JVM spec, and the API documentation is a little bit...
> vague.

Specifically, I was under the impression that Thread.interrupt() should
interrupt a thread that is blocking on an I/O operation (Socket.read() etc)
- otherwise what is InterruptedIOException for? However, from reading posts
to Sun's java discussion forums [*], it appears that this is not the case,
at least for recent JDKs. Is it worth trying to implement this?

Also, regarding interaction between interrupt() and wait(): suppose we have
4 threads. Two of these (1&2) are blocked on wait() for the monitor "a".
Simultaniously, thread 3 calls a.notify() and thread 4 calls
thread1.interrupt(). My guess is that the correct behaviour is for EITHER
thread 1 to wake up normally, but also have its interrupt status flag set,
or for thread 2 to wake up normally and thread 1 to wake up with an
InterruptedException. Is this correct?

regards

  [ bryce ]

[*]:
http://forum2.java.sun.com/forum?14@@.787b6e5f
http://forum2.java.sun.com/forum?14@@.ee778af


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14  2:24   ` Thread.interrupt() Kresten Krab Thorup
  2000-03-14  3:26     ` Thread.interrupt() Bryce McKinlay
  2000-03-14  5:52     ` Thread.interrupt() Jeff Sturm
@ 2000-04-01  0:00     ` Kresten Krab Thorup
  2 siblings, 0 replies; 51+ messages in thread
From: Kresten Krab Thorup @ 2000-04-01  0:00 UTC (permalink / raw)
  To: Bryce McKinlay; +Cc: java-discuss

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 779 bytes --]

See:

http://developer.java.sun.com/developer/bugParade/bugs/4103109.html

The evaluation reads:

We believe Thread.interrupt to be no worse (and no better) than
Thread.stop at interrupting I/O in progress.  Unfortunately, neither of
these calls reliably breaks out of I/O waits.  On some platforms, it is
extremely difficult to implement the desired behavior.

xxxxx@xxxxx 1998-06-25

As of today, the interruptable io has officially deprecated. We are not
going to fix this bug. However, we leave the current implementation as
it is for backward compatibility.

xxxxx@xxxxx 1999-09-12


-- Kresten

Kresten Krab Thorup, Director of Research
Eastfork Object Space (EOS), Margrethepladsen 3, 8000  Ã…rhus C, Denmark
Tel: +45 8732 8787 / Fax: +45 8732 8788 / Mob: +45 2343 4626

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
  2000-03-16  4:08 Thread.interrupt() Miles Sabin
@ 2000-04-01  0:00 ` Miles Sabin
  0 siblings, 0 replies; 51+ messages in thread
From: Miles Sabin @ 2000-04-01  0:00 UTC (permalink / raw)
  To: 'java-discuss@sourceware.cygnus.com'

Boehm, Hans wrote,
> The problem is that with resource revocation there is no 
> standard method that thread A would call to terminate B.

Sure, but why on earth would you expect one?

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14  5:52     ` Thread.interrupt() Jeff Sturm
  2000-03-14 11:02       ` Thread.interrupt() Tom Tromey
  2000-03-14 14:16       ` Thread.interrupt() Bryce McKinlay
@ 2000-04-01  0:00       ` Jeff Sturm
  2 siblings, 0 replies; 51+ messages in thread
From: Jeff Sturm @ 2000-04-01  0:00 UTC (permalink / raw)
  To: Kresten Krab Thorup; +Cc: Bryce McKinlay, java-discuss

Kresten Krab Thorup wrote:
[...]
> As of today, the interruptable io has officially deprecated. We are not
> going to fix this bug. However, we leave the current implementation as
> it is for backward compatibility.
> 
> xxxxx@xxxxx 1999-09-12

IOW, Sun crippled their API because Win32 doesn't handle interruptable
I/O portably.  Not a good policy.

Since Java doesn't support read() with timeouts either, it is easy to
create a "stuck" thread that can never die.

Question: do the libgcj maintainers feel obligated to follow Sun's
interpretation of the JLS?

-- 
Jeff Sturm
jsturm@sigma6.com

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
  2000-03-14  9:57 Thread.interrupt() Boehm, Hans
  2000-03-14 10:52 ` Thread.interrupt() Tom Tromey
  2000-03-14 15:59 ` Thread.interrupt() Jesper Peterson
@ 2000-04-01  0:00 ` Boehm, Hans
  2 siblings, 0 replies; 51+ messages in thread
From: Boehm, Hans @ 2000-04-01  0:00 UTC (permalink / raw)
  To: 'Miles Sabin', java-discuss

It seems to me that there are a bunch of problems with leaving out
interruptable
I/O:

- As Jeff and the Sun bug report point out, there doesn't seem to be a
portable alternative.

- The closest alternative, closing the descriptor, doesn't feel like
reasonable programming
practice.  If I want to stop a worker thread I created, it's not necessarily
my business to
know what file descriptor it's waiting on.  The "technique", if I understand
it correctly,
seems to be a gross violation of modularity.

- I view gcj's goal as providing a Java implementation that is particularly
interoperable
with C/C++.  In the Posix world, there is an approximate equivalent for
thread.interrupt:
pthread_cancel.  (Based on a quick look at the source, recent versins seem
to try to do the
right thing on Linux, in spite of the documentation.)  I think this makes it
highly
desirable that pthread_cancel should work on Java threads.  Once you accept
that, it seems
hard to believe that Thread.interrupt() can't do the right thing.  It seems
to me that
Thread.interrupt() should in fact be implemented (on Posix platforms) using
pthread_cancel,
though it may take some work on the pthreads side to make that fly.

Hans


-----Original Message-----
From: Miles Sabin [ mailto:msabin@cromwellmedia.co.uk ]
Sent: Tuesday, March 14, 2000 6:00 AM
To: java-discuss@sourceware.cygnus.com
Subject: RE: Thread.interrupt()


Jeff Sturm wrote,
> IOW, Sun crippled their API because Win32 doesn't handle 
> interruptable I/O portably.  Not a good policy.
>
> Since Java doesn't support read() with timeouts either, it is 
> easy to create a "stuck" thread that can never die.

The following posting of Doug Lea's on this topic from a while 
back on the advanced-java list is the best response to your
complaint ...

Doug Lea wrote,
> I think the consensus is that Interruptible I/O was a
> reasonable-looking notion that turned out to be a bad idea in
> practice. In fact, I hope it becomes deprecated before it is 
> fully implemented. (Currently, it is very incompletely 
> implemented, at least on Solaris and Win platforms.) The 
> fundamental problem is that there is rarely a reasonable 
> continuation action that can be taken if low-level I/O 
> interrupts.  Most Java programs use buffered or translated 
> I/O classes, which in turn rely on lower-level I/O classes. 
> But there is hardly ever a way for them to roll back or
> forward under a lower level exception. So the only recourse 
> is to abort.
>
> Given this (see http://gee.cs.oswego.edu/dl/cpj/cancel.html ), 
> usually the best way to implement cancellation in I/O is just 
> resource revocation -- asynchronously forcibly closing the 
> stream that the thread is operating on. This results in a 
> generic I/O exception, which can then be used to shut down a 
> thread. This works well (at least on Solaris 1.2. I don't 
> know about other platforms). To play it safe, and force 
> termination whether the thread is actually doing any I/O, you
> should normally do both stream.close() and Thread.interrupt
> ().

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14 15:59 ` Thread.interrupt() Jesper Peterson
@ 2000-04-01  0:00   ` Jesper Peterson
  0 siblings, 0 replies; 51+ messages in thread
From: Jesper Peterson @ 2000-04-01  0:00 UTC (permalink / raw)
  To: java-discuss

"Boehm, Hans" wrote:

>It seems to me that there are a bunch of problems with leaving out
>interruptable
>I/O:
>[...] 
> - The closest alternative, closing the descriptor, doesn't feel like
> reasonable programming
> practice.  If I want to stop a worker thread I created, it's not necessarily
> my business to
> know what file descriptor it's waiting on.  The "technique", if I understand
> it correctly,
> seems to be a gross violation of modularity.

Not at all. Doug Lea's approach works very well for me. In fact I have an
application that depends on it. An object extends or contains the thread,
that object holds the state of the resources and I 'cancel' via that object.

It is essential that it be possible to block on I/O and cancel at will from
another thread. Otherwise a number of interesting applications cannot be
implemented. Granted I could poll, but I'm old-fashioned, I don't waste CPU
cycles no matter how many of them there are.

-- 
Jesper Peterson                   - Are my methods unsound?
Senior Software Developer         - I don't see any method at all Sir.
eSec Limited                               --- Apocalypse Now
http://www.esec.com.au

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
  2000-03-15 11:57 Thread.interrupt() Miles Sabin
@ 2000-04-01  0:00 ` Miles Sabin
  0 siblings, 0 replies; 51+ messages in thread
From: Miles Sabin @ 2000-04-01  0:00 UTC (permalink / raw)
  To: java-discuss

Boehm, Hans wrote,
> The crucial problem with this is that at least every class in 
> the system that performs blocking I/O has to play by these 
> rules.

The same applies to Thread.interrupt().

Interrupts can be cleared or deferred indefinitely, so Thread.
interrupt() isn't a guaranteed way of cancelling a thread which
doesn't respect the protocol.

Much the same goes for the complaint that resource revocation
violates encapsulation: if it's unexpected an interrupt 
represents a pretty violent disruption of control flow.
Of course an interrupt isn't always unexpected, but then 
neither is resource revocation.

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
  2000-03-14 16:30 Thread.interrupt() Boehm, Hans
  2000-03-14 17:17 ` Thread.interrupt() Jesper Peterson
@ 2000-04-01  0:00 ` Boehm, Hans
  1 sibling, 0 replies; 51+ messages in thread
From: Boehm, Hans @ 2000-04-01  0:00 UTC (permalink / raw)
  To: 'Jesper Peterson', java-discuss

I agree that this approach works well in some (many?) cases.  I also agree
that restarting the I/O after an interruption is unlikely to be practical.

But I'm not convinced this is a general solution.

What bothers me is the following scenario:

Thread A starts worker threads B, C, and D.

Thread B makes 27 nested method calls, each in a different class, written by
different authors.
The 28th call decides that it needs some information from a file somewhere
halfway around the world, and opens a connection to the server.  The access
access takes a long time, e.g. because the server is accessible only by 1200
baud
modem.

Threads C and D so something else using some of the same classes.

Thread A decides it wants to cancel thread B.  How can it close the file
descriptor,
which is located in a local variable 28 frames down in B's stack?  Even if B
cooperated,
and put the file descriptor in some public place, there's no obvious place
to put it.
It can't put it in a fixed global place, since C and D might overwrite it.

The second problem, apparent from the Sun bug report, is that this approach
fails if
the underlying close and read implementation each acquire the same lock,
since the
close will just block.  Apparently some version of Solaris do this.  Before
this discussion,
that would have seemed like the obvious, safe implementation to me.  Thus
I'd be
surprised if this behavior occurred only in Solaris.

Hans
 
-----Original Message-----
From: Jesper Peterson [ mailto:jep@esec.com.au ]
Sent: Tuesday, March 14, 2000 3:59 PM
To: java-discuss@sourceware.cygnus.com
Subject: Re: Thread.interrupt()


"Boehm, Hans" wrote:

>It seems to me that there are a bunch of problems with leaving out
>interruptable
>I/O:
>[...] 
> - The closest alternative, closing the descriptor, doesn't feel like
> reasonable programming
> practice.  If I want to stop a worker thread I created, it's not
necessarily
> my business to
> know what file descriptor it's waiting on.  The "technique", if I
understand
> it correctly,
> seems to be a gross violation of modularity.

Not at all. Doug Lea's approach works very well for me. In fact I have an
application that depends on it. An object extends or contains the thread,
that object holds the state of the resources and I 'cancel' via that object.

It is essential that it be possible to block on I/O and cancel at will from
another thread. Otherwise a number of interesting applications cannot be
implemented. Granted I could poll, but I'm old-fashioned, I don't waste CPU
cycles no matter how many of them there are.

-- 
Jesper Peterson                   - Are my methods unsound?
Senior Software Developer         - I don't see any method at all Sir.
eSec Limited                               --- Apocalypse Now
http://www.esec.com.au

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
  2000-03-14 11:26 Thread.interrupt() Boehm, Hans
@ 2000-04-01  0:00 ` Boehm, Hans
  0 siblings, 0 replies; 51+ messages in thread
From: Boehm, Hans @ 2000-04-01  0:00 UTC (permalink / raw)
  To: 'Tom Tromey', Boehm, Hans; +Cc: 'Miles Sabin', java-discuss

I think we are asking two different questions, and I'm probably overly
optimistic.

If the question is:  "Can Thread.interrupt() be implemented in terms of
pthread_cancel,
without relying on undocumented properties the pthread implementation?" then
the answer
is almost certainly no.

But there are lots of things you can't do without relying on extensions to
the pthreads
implementation (e.g. garbage collection, reasonable cost reference counting,
etc.)

So my question was really: "Can I extend the pthreads
implementation/documentation such that
Thread.interrupt() is implementable in terms of pthread_cancel()?"  In that
case,
the answer is likely to be "yes".

It seems to me that this is a reasonable approach for getting the
functionality on Linux.
Java is likely to eventually be either the most important client of
pthreads, or certainly
one of the most important clients.  Adding minor extensions to make them
cooperate seems
more than reasonable.

It does mean that you won't get instantaneous support for this feature on
all platforms.
But at least you have a path to get there on each platform.

I haven't a clue whether, for example, the linux_threads implementation,
would actually
need to be changed.  Certainly more of its behavior would have to be exposed
to gcj.
(I implemented this once in a different context while I was working for SGI.
My recollection
is that in that case essentially no pthread code changes were required in
the end.)

Hans

-----Original Message-----
From: Tom Tromey [ mailto:tromey@cygnus.com ]
Sent: Tuesday, March 14, 2000 10:52 AM
To: Boehm, Hans
Cc: 'Miles Sabin'; java-discuss@sourceware.cygnus.com
Subject: RE: Thread.interrupt()

Hans> It seems to me that Thread.interrupt() should in fact be
Hans> implemented (on Posix platforms) using pthread_cancel, though it
Hans> may take some work on the pthreads side to make that fly.

I don't see how this can be done, because I don't see how you can stop
a cancellation in progress (eg, throwing an exception from a cleanup
handler is undefined behavior).  Bryce and I have been talking about
just implementing condition variables on our own for POSIX, since the
POSIX and Java models don't line up enough.  I'd love to be wrong
about this.

Tom

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14 17:17 ` Thread.interrupt() Jesper Peterson
  2000-03-14 17:27   ` Thread.interrupt() Tom Tromey
@ 2000-04-01  0:00   ` Jesper Peterson
  1 sibling, 0 replies; 51+ messages in thread
From: Jesper Peterson @ 2000-04-01  0:00 UTC (permalink / raw)
  To: Boehm, Hans; +Cc: java-discuss

"Boehm, Hans" wrote:
>[...]
> Thread A decides it wants to cancel thread B.  How can it close the file
> descriptor,
> which is located in a local variable 28 frames down in B's stack?  Even if B
> cooperated,
> and put the file descriptor in some public place, there's no obvious place
> to put it.

Fair enough, it isn't a general solution and I definitely agree that
Thread.interrupt() is far preferable. The discussion so far was suggesting
that interruptable I/O had been given up for dead, and I wanted to point
out that at least one of interuptable I/O or resource revocation (preferably
both) *must* work. If neither works GCJ or Java generally would not be very
useful to me.

What I really need is for Thread.interrupt() to work, and an atomic
readIfNotInterrupted() so a single interrupt is guaranteed to make a thread
fall through a read() or alternatively make Thread.destroy() work.

I need to be able to cancel a thread that does this: while(!done){read()}
even if the read blocks. Resource revocation does this very nicely for
the specific code that I am working on.

>The second problem, apparent from the Sun bug report, is that this approach
>fails if
>the underlying close and read implementation each acquire the same lock,
>since the

I would expect the underlying implementation to not hold the lock while
waiting for I/O. If the underlying platform is badly implemented either
for threads, I/O or both I would not expect Java applications that use
these semantics to work. Disallowing it just because there is at least
one platform where it will not work opens up a can of worms. There will
always be some platform that cannot properly implement a given behaviour,
the product of all platforms will probably disallow all useful behaviours.

-- 
Jesper Peterson                   - Are my methods unsound?
Senior Software Developer         - I don't see any method at all Sir.
eSec Limited                               --- Apocalypse Now
http://www.esec.com.au

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14 11:02       ` Thread.interrupt() Tom Tromey
@ 2000-04-01  0:00         ` Tom Tromey
  0 siblings, 0 replies; 51+ messages in thread
From: Tom Tromey @ 2000-04-01  0:00 UTC (permalink / raw)
  To: Jeff Sturm; +Cc: Kresten Krab Thorup, Bryce McKinlay, java-discuss

Jeff> Question: do the libgcj maintainers feel obligated to follow
Jeff> Sun's interpretation of the JLS?

That's a good question.  I think the basic answer is "yes".  We think
compatibility is good.

However, I don't interpret that to mean strict compliance to a
particular version of the JDK.  Nor do I interpret that to mean bug
compatibility with JDK.

This is a very tricky area, and about the best we can do is examine
things on a case-by-case basis.  Generally speaking there doesn't seem
to be a "right" approach, especially given that in some situations,
like this one, Sun is willing to change the spec to suit defects in
their implementation (or at least in their research).

Tom

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
  2000-03-15 13:06 Thread.interrupt() Miles Sabin
@ 2000-04-01  0:00 ` Miles Sabin
  0 siblings, 0 replies; 51+ messages in thread
From: Miles Sabin @ 2000-04-01  0:00 UTC (permalink / raw)
  To: 'java-discuss@sourceware.cygnus.com'

Boehm, Hans wrote,
> In the case of resource invocation, there is no defined 
> protocol, and thus essentially no libraries that abide by it.

Well, there is, sort of.

Resource revocation implies that the current or next use of
the resource will fail. That should result in an exception
throw (an IOException in this particular case). In general I
would expect well behaved libraries to respond gracefully in
the face of such an event.

That's not to say that there aren't buggy libraries that'll
try and limp on in circumstances where they should abort, but
much the same goes for interruption.

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/



^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
  2000-03-15  5:51 Thread.interrupt() Miles Sabin
@ 2000-04-01  0:00 ` Miles Sabin
  0 siblings, 0 replies; 51+ messages in thread
From: Miles Sabin @ 2000-04-01  0:00 UTC (permalink / raw)
  To: java-discuss

Boehm, Hans wrote,
> Thread A decides it wants to cancel thread B.  How can it 
> close the file descriptor, which is located in a local 
> variable 28 frames down in B's stack?  Even if B cooperated,
> and put the file descriptor in some public place, there's no 
> obvious place to put it. It can't put it in a fixed global 
> place, since C and D might overwrite it.

I don't see this as a problem specific to interruptable IO or
even concurrency. Similar issues might arise in, for example, 
(syntactic) error handling/recovery in a recursive descent 
parser, or any number of other scenarios where the stack is
used to encode an objects state.

In fact, it looks like a straightforward software design issue 
to me. Effectively what you're saying is that cancellation is a 
first class aspect of the behaviour associated with thread B. 
That being so it should be exposed at the interface level and
then implemented in whatever the appropriate way is. For a 
simple example: B's Runnable instance might have a register() 
method to allow the 28-frame-down FD to be associated with the 
the state of thread B as a whole; and a cancel() method 
accessible to A which closes it.

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14 17:27   ` Thread.interrupt() Tom Tromey
@ 2000-04-01  0:00     ` Tom Tromey
  0 siblings, 0 replies; 51+ messages in thread
From: Tom Tromey @ 2000-04-01  0:00 UTC (permalink / raw)
  To: Jesper Peterson; +Cc: Boehm, Hans, java-discuss

Jesper> and I wanted to point out that at least one of interuptable
Jesper> I/O or resource revocation (preferably both) *must* work. If
Jesper> neither works GCJ or Java generally would not be very useful
Jesper> to me.

I think both should work, if possible, in our implementation.

For Thread.interrupt(), I agree that the idea of restartability is
bogus.  That would require too much care in too many places, I think.
However, I still see this as useful for aborting I/O operations
partway through.

Tom

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
  2000-03-15 13:52 Thread.interrupt() Boehm, Hans
@ 2000-04-01  0:00 ` Boehm, Hans
  0 siblings, 0 replies; 51+ messages in thread
From: Boehm, Hans @ 2000-04-01  0:00 UTC (permalink / raw)
  To: 'Miles Sabin', 'java-discuss@sourceware.cygnus.com'

Miles Sabin wrote:

>Boehm, Hans wrote,
>> In the case of resource invocation, there is no defined 
>> protocol, and thus essentially no libraries that abide by it.

>Well, there is, sort of.

>Resource revocation implies that the current or next use of
>the resource will fail. That should result in an exception
>throw (an IOException in this particular case). In general I
>would expect well behaved libraries to respond gracefully in
>the face of such an event.

That's not the issue.  The problem is that with resource revocation
there is no standard method that thread A would call to terminate B.
Equivalently, there is no protocol that would allow thread A to locate
the resource it should revoke to terminate thread B.  I haven't a clue how
to terminate a thread that might hang during name lookup in a standard
library if I'm constrained to use resource revocation.

Hans

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14 14:16       ` Thread.interrupt() Bryce McKinlay
  2000-03-14 16:09         ` Thread.interrupt() Godmar Back
@ 2000-04-01  0:00         ` Bryce McKinlay
  1 sibling, 0 replies; 51+ messages in thread
From: Bryce McKinlay @ 2000-04-01  0:00 UTC (permalink / raw)
  To: Jeff Sturm; +Cc: Kresten Krab Thorup, java-discuss

Jeff Sturm wrote:

> IOW, Sun crippled their API because Win32 doesn't handle interruptable
> I/O portably.  Not a good policy.
>
> Since Java doesn't support read() with timeouts either, it is easy to
> create a "stuck" thread that can never die.

Well, according to the JDK 1.2 API docs, it does for socket reads. We don't
implement this properly yet, though.

public void setSoTimeout(int timeout)
                  throws SocketException

... "With this option set to a non-zero timeout, a read() call on the
InputStream associated with this Socket will block for only this amount of
time. If the timeout expires, a java.io.InterruptedIOException is raised,
though the Socket is still valid. " ...

On the other hand, the behaviour of interrupt() was never well-specified.
Another way to unstick a blocked thread is to close the underlying socket
from another thread. Arguably, a good interrupt() implementation would be
better though.

regards

  [ bryce ]


^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
  2000-03-15 12:55 Thread.interrupt() Boehm, Hans
@ 2000-04-01  0:00 ` Boehm, Hans
  0 siblings, 0 replies; 51+ messages in thread
From: Boehm, Hans @ 2000-04-01  0:00 UTC (permalink / raw)
  To: 'Miles Sabin'; +Cc: 'java-discuss@sourceware.cygnus.com'

[Miles Sabin wrote:]
>Boehm, Hans wrote,
>> The crucial problem with this is that at least every class in 
>> the system that performs blocking I/O has to play by these 
>> rules.
>
>The same applies to Thread.interrupt().
>
>Interrupts can be cleared or deferred indefinitely, so Thread.
>interrupt() isn't a guaranteed way of cancelling a thread which
>doesn't respect the protocol.

Right.  But I think there is a general expectation that library
routines shouldn't defer interrupts indefinitely or ignore them.
And I would expect that most existing libaries abide by these rules.
(And most of those that ignore the issue probably don't behave too badly
with respect to this protocol.)

In the case of resource invocation, there is no defined protocol, and
thus essentially no libraries that abide by it.

Hans

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
  2000-03-14 10:52 ` Thread.interrupt() Tom Tromey
@ 2000-04-01  0:00   ` Tom Tromey
  0 siblings, 0 replies; 51+ messages in thread
From: Tom Tromey @ 2000-04-01  0:00 UTC (permalink / raw)
  To: Boehm, Hans; +Cc: 'Miles Sabin', java-discuss

Hans> It seems to me that there are a bunch of problems with leaving
Hans> out interruptable I/O:

I agree.  Also I don't see any text in the 1.3 online docs to indicate
that this is deprecated; depending on the bug parade seems suboptimal.

Hans> It seems to me that Thread.interrupt() should in fact be
Hans> implemented (on Posix platforms) using pthread_cancel, though it
Hans> may take some work on the pthreads side to make that fly.

I don't see how this can be done, because I don't see how you can stop
a cancellation in progress (eg, throwing an exception from a cleanup
handler is undefined behavior).  Bryce and I have been talking about
just implementing condition variables on our own for POSIX, since the
POSIX and Java models don't line up enough.  I'd love to be wrong
about this.

Tom

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14  3:26     ` Thread.interrupt() Bryce McKinlay
@ 2000-04-01  0:00       ` Bryce McKinlay
  0 siblings, 0 replies; 51+ messages in thread
From: Bryce McKinlay @ 2000-04-01  0:00 UTC (permalink / raw)
  To: Kresten Krab Thorup; +Cc: java-discuss

Thanks for the link. There is another, long discussion of the subject from
a Sun engineer at
http://developer.java.sun.com/developer/bugParade/bugs/4154947.html

Basically it appears that they deprecated it because it didn't work on
Win32. Interruptable I/O seems like it would be a nice feature to have,
but given that it is deprecated I don't think I'll bother to implement it
now.

regards

  [ bryce ]


Kresten Krab Thorup wrote:

> As of today, the interruptable io has officially deprecated. We are not
> going to fix this bug. However, we leave the current implementation as
> it is for backward compatibility.
>
> xxxxx@xxxxx 1999-09-12

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14 16:09         ` Thread.interrupt() Godmar Back
@ 2000-04-01  0:00           ` Godmar Back
  0 siblings, 0 replies; 51+ messages in thread
From: Godmar Back @ 2000-04-01  0:00 UTC (permalink / raw)
  To: Bryce McKinlay; +Cc: Jeff Sturm, Kresten Krab Thorup, java-discuss

> 
> Jeff Sturm wrote:
> 
> > IOW, Sun crippled their API because Win32 doesn't handle interruptable
> > I/O portably.  Not a good policy.
> >
> > Since Java doesn't support read() with timeouts either, it is easy to
> > create a "stuck" thread that can never die.
> 
> Well, according to the JDK 1.2 API docs, it does for socket reads. We don't
> implement this properly yet, though.
> 
> public void setSoTimeout(int timeout)
>                   throws SocketException
> 

I implemented both InterruptedIOException and the socket timeout stuff
in Kaffe a while ago.  You could use SoInterrupt.java and SoTimeout.java
from the regression directory if you need test cases.

I tend to agree with Lea's (or whoever's) argument that a meaningful 
continuation after an interrupted I/O is rarely possible.  IIRC, the
argument he gave was that the interruption will often occur deep inside
a layered hierarchy of BufferReader/StreamReader/Reader etc. which cannot
deal with interrupted I/O.  One issue is that you may end up with 
partial reads/writes after an interruption, which need to be dealt with.
In other words, the buffer classes would have to be interruption-aware
and "restartable".   Otherwise, data may be sent or received twice.
Granted, these classes could be fixed, but at a higher cost in 
implementation complexity.  For this reason, I think that the more 
pragmatic "close-the-socket" approach may be preferable.

	- Godmar

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
@ 2000-03-16  4:08 Miles Sabin
  2000-04-01  0:00 ` Thread.interrupt() Miles Sabin
  0 siblings, 1 reply; 51+ messages in thread
From: Miles Sabin @ 2000-03-16  4:08 UTC (permalink / raw)
  To: 'java-discuss@sourceware.cygnus.com'

Boehm, Hans wrote,
> The problem is that with resource revocation there is no 
> standard method that thread A would call to terminate B.

Sure, but why on earth would you expect one?

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
@ 2000-03-15 13:52 Boehm, Hans
  2000-04-01  0:00 ` Thread.interrupt() Boehm, Hans
  0 siblings, 1 reply; 51+ messages in thread
From: Boehm, Hans @ 2000-03-15 13:52 UTC (permalink / raw)
  To: 'Miles Sabin', 'java-discuss@sourceware.cygnus.com'

Miles Sabin wrote:

>Boehm, Hans wrote,
>> In the case of resource invocation, there is no defined 
>> protocol, and thus essentially no libraries that abide by it.

>Well, there is, sort of.

>Resource revocation implies that the current or next use of
>the resource will fail. That should result in an exception
>throw (an IOException in this particular case). In general I
>would expect well behaved libraries to respond gracefully in
>the face of such an event.

That's not the issue.  The problem is that with resource revocation
there is no standard method that thread A would call to terminate B.
Equivalently, there is no protocol that would allow thread A to locate
the resource it should revoke to terminate thread B.  I haven't a clue how
to terminate a thread that might hang during name lookup in a standard
library if I'm constrained to use resource revocation.

Hans

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
@ 2000-03-15 13:06 Miles Sabin
  2000-04-01  0:00 ` Thread.interrupt() Miles Sabin
  0 siblings, 1 reply; 51+ messages in thread
From: Miles Sabin @ 2000-03-15 13:06 UTC (permalink / raw)
  To: 'java-discuss@sourceware.cygnus.com'

Boehm, Hans wrote,
> In the case of resource invocation, there is no defined 
> protocol, and thus essentially no libraries that abide by it.

Well, there is, sort of.

Resource revocation implies that the current or next use of
the resource will fail. That should result in an exception
throw (an IOException in this particular case). In general I
would expect well behaved libraries to respond gracefully in
the face of such an event.

That's not to say that there aren't buggy libraries that'll
try and limp on in circumstances where they should abort, but
much the same goes for interruption.

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/



^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
@ 2000-03-15 12:55 Boehm, Hans
  2000-04-01  0:00 ` Thread.interrupt() Boehm, Hans
  0 siblings, 1 reply; 51+ messages in thread
From: Boehm, Hans @ 2000-03-15 12:55 UTC (permalink / raw)
  To: 'Miles Sabin'; +Cc: 'java-discuss@sourceware.cygnus.com'

[Miles Sabin wrote:]
>Boehm, Hans wrote,
>> The crucial problem with this is that at least every class in 
>> the system that performs blocking I/O has to play by these 
>> rules.
>
>The same applies to Thread.interrupt().
>
>Interrupts can be cleared or deferred indefinitely, so Thread.
>interrupt() isn't a guaranteed way of cancelling a thread which
>doesn't respect the protocol.

Right.  But I think there is a general expectation that library
routines shouldn't defer interrupts indefinitely or ignore them.
And I would expect that most existing libaries abide by these rules.
(And most of those that ignore the issue probably don't behave too badly
with respect to this protocol.)

In the case of resource invocation, there is no defined protocol, and
thus essentially no libraries that abide by it.

Hans

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
@ 2000-03-15 11:57 Miles Sabin
  2000-04-01  0:00 ` Thread.interrupt() Miles Sabin
  0 siblings, 1 reply; 51+ messages in thread
From: Miles Sabin @ 2000-03-15 11:57 UTC (permalink / raw)
  To: java-discuss

Boehm, Hans wrote,
> The crucial problem with this is that at least every class in 
> the system that performs blocking I/O has to play by these 
> rules.

The same applies to Thread.interrupt().

Interrupts can be cleared or deferred indefinitely, so Thread.
interrupt() isn't a guaranteed way of cancelling a thread which
doesn't respect the protocol.

Much the same goes for the complaint that resource revocation
violates encapsulation: if it's unexpected an interrupt 
represents a pretty violent disruption of control flow.
Of course an interrupt isn't always unexpected, but then 
neither is resource revocation.

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
@ 2000-03-15 11:38 Boehm, Hans
  2000-04-01  0:00 ` Thread.interrupt() Boehm, Hans
  0 siblings, 1 reply; 51+ messages in thread
From: Boehm, Hans @ 2000-03-15 11:38 UTC (permalink / raw)
  To: 'Miles Sabin', java-discuss

I agree that you can invent a protocol that will make it possible to
interrupt a thread blocked on I/O by closing a file descriptor (assuming
that closing a file descriptor actually terminates a read).  The crucial
problem with this is that at least every class in the system that performs
blocking I/O has to play by these rules.  In most cases, you  won't have
control over all of them.  And those implemented by others won't play by
your rules.  For example, I'd be surprised if something like
java.net.URLConnection gave access to all file descriptors it might wait on,
e.g. for name lookups.

Thread.interrupt() was intended to provide a general solution to this
problem, effectively by standardizing the protocol (and making it a bit more
general in the process). 

Hans

-----Original Message-----
From: Miles Sabin [ mailto:msabin@cromwellmedia.co.uk ]
Sent: Wednesday, March 15, 2000 5:51 AM
To: java-discuss@sourceware.cygnus.com
Subject: RE: Thread.interrupt()


Boehm, Hans wrote,
> Thread A decides it wants to cancel thread B.  How can it 
> close the file descriptor, which is located in a local 
> variable 28 frames down in B's stack?  Even if B cooperated,
> and put the file descriptor in some public place, there's no 
> obvious place to put it. It can't put it in a fixed global 
> place, since C and D might overwrite it.

I don't see this as a problem specific to interruptable IO or
even concurrency. Similar issues might arise in, for example, 
(syntactic) error handling/recovery in a recursive descent 
parser, or any number of other scenarios where the stack is
used to encode an objects state.

In fact, it looks like a straightforward software design issue 
to me. Effectively what you're saying is that cancellation is a 
first class aspect of the behaviour associated with thread B. 
That being so it should be exposed at the interface level and
then implemented in whatever the appropriate way is. For a 
simple example: B's Runnable instance might have a register() 
method to allow the 28-frame-down FD to be associated with the 
the state of thread B as a whole; and a cancel() method 
accessible to A which closes it.

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
@ 2000-03-15  5:51 Miles Sabin
  2000-04-01  0:00 ` Thread.interrupt() Miles Sabin
  0 siblings, 1 reply; 51+ messages in thread
From: Miles Sabin @ 2000-03-15  5:51 UTC (permalink / raw)
  To: java-discuss

Boehm, Hans wrote,
> Thread A decides it wants to cancel thread B.  How can it 
> close the file descriptor, which is located in a local 
> variable 28 frames down in B's stack?  Even if B cooperated,
> and put the file descriptor in some public place, there's no 
> obvious place to put it. It can't put it in a fixed global 
> place, since C and D might overwrite it.

I don't see this as a problem specific to interruptable IO or
even concurrency. Similar issues might arise in, for example, 
(syntactic) error handling/recovery in a recursive descent 
parser, or any number of other scenarios where the stack is
used to encode an objects state.

In fact, it looks like a straightforward software design issue 
to me. Effectively what you're saying is that cancellation is a 
first class aspect of the behaviour associated with thread B. 
That being so it should be exposed at the interface level and
then implemented in whatever the appropriate way is. For a 
simple example: B's Runnable instance might have a register() 
method to allow the 28-frame-down FD to be associated with the 
the state of thread B as a whole; and a cancel() method 
accessible to A which closes it.

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14 17:17 ` Thread.interrupt() Jesper Peterson
@ 2000-03-14 17:27   ` Tom Tromey
  2000-04-01  0:00     ` Thread.interrupt() Tom Tromey
  2000-04-01  0:00   ` Thread.interrupt() Jesper Peterson
  1 sibling, 1 reply; 51+ messages in thread
From: Tom Tromey @ 2000-03-14 17:27 UTC (permalink / raw)
  To: Jesper Peterson; +Cc: Boehm, Hans, java-discuss

Jesper> and I wanted to point out that at least one of interuptable
Jesper> I/O or resource revocation (preferably both) *must* work. If
Jesper> neither works GCJ or Java generally would not be very useful
Jesper> to me.

I think both should work, if possible, in our implementation.

For Thread.interrupt(), I agree that the idea of restartability is
bogus.  That would require too much care in too many places, I think.
However, I still see this as useful for aborting I/O operations
partway through.

Tom

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14 16:30 Thread.interrupt() Boehm, Hans
@ 2000-03-14 17:17 ` Jesper Peterson
  2000-03-14 17:27   ` Thread.interrupt() Tom Tromey
  2000-04-01  0:00   ` Thread.interrupt() Jesper Peterson
  2000-04-01  0:00 ` Thread.interrupt() Boehm, Hans
  1 sibling, 2 replies; 51+ messages in thread
From: Jesper Peterson @ 2000-03-14 17:17 UTC (permalink / raw)
  To: Boehm, Hans; +Cc: java-discuss

"Boehm, Hans" wrote:
>[...]
> Thread A decides it wants to cancel thread B.  How can it close the file
> descriptor,
> which is located in a local variable 28 frames down in B's stack?  Even if B
> cooperated,
> and put the file descriptor in some public place, there's no obvious place
> to put it.

Fair enough, it isn't a general solution and I definitely agree that
Thread.interrupt() is far preferable. The discussion so far was suggesting
that interruptable I/O had been given up for dead, and I wanted to point
out that at least one of interuptable I/O or resource revocation (preferably
both) *must* work. If neither works GCJ or Java generally would not be very
useful to me.

What I really need is for Thread.interrupt() to work, and an atomic
readIfNotInterrupted() so a single interrupt is guaranteed to make a thread
fall through a read() or alternatively make Thread.destroy() work.

I need to be able to cancel a thread that does this: while(!done){read()}
even if the read blocks. Resource revocation does this very nicely for
the specific code that I am working on.

>The second problem, apparent from the Sun bug report, is that this approach
>fails if
>the underlying close and read implementation each acquire the same lock,
>since the

I would expect the underlying implementation to not hold the lock while
waiting for I/O. If the underlying platform is badly implemented either
for threads, I/O or both I would not expect Java applications that use
these semantics to work. Disallowing it just because there is at least
one platform where it will not work opens up a can of worms. There will
always be some platform that cannot properly implement a given behaviour,
the product of all platforms will probably disallow all useful behaviours.

-- 
Jesper Peterson                   - Are my methods unsound?
Senior Software Developer         - I don't see any method at all Sir.
eSec Limited                               --- Apocalypse Now
http://www.esec.com.au

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
@ 2000-03-14 16:30 Boehm, Hans
  2000-03-14 17:17 ` Thread.interrupt() Jesper Peterson
  2000-04-01  0:00 ` Thread.interrupt() Boehm, Hans
  0 siblings, 2 replies; 51+ messages in thread
From: Boehm, Hans @ 2000-03-14 16:30 UTC (permalink / raw)
  To: 'Jesper Peterson', java-discuss

I agree that this approach works well in some (many?) cases.  I also agree
that restarting the I/O after an interruption is unlikely to be practical.

But I'm not convinced this is a general solution.

What bothers me is the following scenario:

Thread A starts worker threads B, C, and D.

Thread B makes 27 nested method calls, each in a different class, written by
different authors.
The 28th call decides that it needs some information from a file somewhere
halfway around the world, and opens a connection to the server.  The access
access takes a long time, e.g. because the server is accessible only by 1200
baud
modem.

Threads C and D so something else using some of the same classes.

Thread A decides it wants to cancel thread B.  How can it close the file
descriptor,
which is located in a local variable 28 frames down in B's stack?  Even if B
cooperated,
and put the file descriptor in some public place, there's no obvious place
to put it.
It can't put it in a fixed global place, since C and D might overwrite it.

The second problem, apparent from the Sun bug report, is that this approach
fails if
the underlying close and read implementation each acquire the same lock,
since the
close will just block.  Apparently some version of Solaris do this.  Before
this discussion,
that would have seemed like the obvious, safe implementation to me.  Thus
I'd be
surprised if this behavior occurred only in Solaris.

Hans
 
-----Original Message-----
From: Jesper Peterson [ mailto:jep@esec.com.au ]
Sent: Tuesday, March 14, 2000 3:59 PM
To: java-discuss@sourceware.cygnus.com
Subject: Re: Thread.interrupt()


"Boehm, Hans" wrote:

>It seems to me that there are a bunch of problems with leaving out
>interruptable
>I/O:
>[...] 
> - The closest alternative, closing the descriptor, doesn't feel like
> reasonable programming
> practice.  If I want to stop a worker thread I created, it's not
necessarily
> my business to
> know what file descriptor it's waiting on.  The "technique", if I
understand
> it correctly,
> seems to be a gross violation of modularity.

Not at all. Doug Lea's approach works very well for me. In fact I have an
application that depends on it. An object extends or contains the thread,
that object holds the state of the resources and I 'cancel' via that object.

It is essential that it be possible to block on I/O and cancel at will from
another thread. Otherwise a number of interesting applications cannot be
implemented. Granted I could poll, but I'm old-fashioned, I don't waste CPU
cycles no matter how many of them there are.

-- 
Jesper Peterson                   - Are my methods unsound?
Senior Software Developer         - I don't see any method at all Sir.
eSec Limited                               --- Apocalypse Now
http://www.esec.com.au

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14 14:16       ` Thread.interrupt() Bryce McKinlay
@ 2000-03-14 16:09         ` Godmar Back
  2000-04-01  0:00           ` Thread.interrupt() Godmar Back
  2000-04-01  0:00         ` Thread.interrupt() Bryce McKinlay
  1 sibling, 1 reply; 51+ messages in thread
From: Godmar Back @ 2000-03-14 16:09 UTC (permalink / raw)
  To: Bryce McKinlay; +Cc: Jeff Sturm, Kresten Krab Thorup, java-discuss

> 
> Jeff Sturm wrote:
> 
> > IOW, Sun crippled their API because Win32 doesn't handle interruptable
> > I/O portably.  Not a good policy.
> >
> > Since Java doesn't support read() with timeouts either, it is easy to
> > create a "stuck" thread that can never die.
> 
> Well, according to the JDK 1.2 API docs, it does for socket reads. We don't
> implement this properly yet, though.
> 
> public void setSoTimeout(int timeout)
>                   throws SocketException
> 

I implemented both InterruptedIOException and the socket timeout stuff
in Kaffe a while ago.  You could use SoInterrupt.java and SoTimeout.java
from the regression directory if you need test cases.

I tend to agree with Lea's (or whoever's) argument that a meaningful 
continuation after an interrupted I/O is rarely possible.  IIRC, the
argument he gave was that the interruption will often occur deep inside
a layered hierarchy of BufferReader/StreamReader/Reader etc. which cannot
deal with interrupted I/O.  One issue is that you may end up with 
partial reads/writes after an interruption, which need to be dealt with.
In other words, the buffer classes would have to be interruption-aware
and "restartable".   Otherwise, data may be sent or received twice.
Granted, these classes could be fixed, but at a higher cost in 
implementation complexity.  For this reason, I think that the more 
pragmatic "close-the-socket" approach may be preferable.

	- Godmar

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14  9:57 Thread.interrupt() Boehm, Hans
  2000-03-14 10:52 ` Thread.interrupt() Tom Tromey
@ 2000-03-14 15:59 ` Jesper Peterson
  2000-04-01  0:00   ` Thread.interrupt() Jesper Peterson
  2000-04-01  0:00 ` Thread.interrupt() Boehm, Hans
  2 siblings, 1 reply; 51+ messages in thread
From: Jesper Peterson @ 2000-03-14 15:59 UTC (permalink / raw)
  To: java-discuss

"Boehm, Hans" wrote:

>It seems to me that there are a bunch of problems with leaving out
>interruptable
>I/O:
>[...] 
> - The closest alternative, closing the descriptor, doesn't feel like
> reasonable programming
> practice.  If I want to stop a worker thread I created, it's not necessarily
> my business to
> know what file descriptor it's waiting on.  The "technique", if I understand
> it correctly,
> seems to be a gross violation of modularity.

Not at all. Doug Lea's approach works very well for me. In fact I have an
application that depends on it. An object extends or contains the thread,
that object holds the state of the resources and I 'cancel' via that object.

It is essential that it be possible to block on I/O and cancel at will from
another thread. Otherwise a number of interesting applications cannot be
implemented. Granted I could poll, but I'm old-fashioned, I don't waste CPU
cycles no matter how many of them there are.

-- 
Jesper Peterson                   - Are my methods unsound?
Senior Software Developer         - I don't see any method at all Sir.
eSec Limited                               --- Apocalypse Now
http://www.esec.com.au

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14  5:52     ` Thread.interrupt() Jeff Sturm
  2000-03-14 11:02       ` Thread.interrupt() Tom Tromey
@ 2000-03-14 14:16       ` Bryce McKinlay
  2000-03-14 16:09         ` Thread.interrupt() Godmar Back
  2000-04-01  0:00         ` Thread.interrupt() Bryce McKinlay
  2000-04-01  0:00       ` Thread.interrupt() Jeff Sturm
  2 siblings, 2 replies; 51+ messages in thread
From: Bryce McKinlay @ 2000-03-14 14:16 UTC (permalink / raw)
  To: Jeff Sturm; +Cc: Kresten Krab Thorup, java-discuss

Jeff Sturm wrote:

> IOW, Sun crippled their API because Win32 doesn't handle interruptable
> I/O portably.  Not a good policy.
>
> Since Java doesn't support read() with timeouts either, it is easy to
> create a "stuck" thread that can never die.

Well, according to the JDK 1.2 API docs, it does for socket reads. We don't
implement this properly yet, though.

public void setSoTimeout(int timeout)
                  throws SocketException

... "With this option set to a non-zero timeout, a read() call on the
InputStream associated with this Socket will block for only this amount of
time. If the timeout expires, a java.io.InterruptedIOException is raised,
though the Socket is still valid. " ...

On the other hand, the behaviour of interrupt() was never well-specified.
Another way to unstick a blocked thread is to close the underlying socket
from another thread. Arguably, a good interrupt() implementation would be
better though.

regards

  [ bryce ]


^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
@ 2000-03-14 11:26 Boehm, Hans
  2000-04-01  0:00 ` Thread.interrupt() Boehm, Hans
  0 siblings, 1 reply; 51+ messages in thread
From: Boehm, Hans @ 2000-03-14 11:26 UTC (permalink / raw)
  To: 'Tom Tromey', Boehm, Hans; +Cc: 'Miles Sabin', java-discuss

I think we are asking two different questions, and I'm probably overly
optimistic.

If the question is:  "Can Thread.interrupt() be implemented in terms of
pthread_cancel,
without relying on undocumented properties the pthread implementation?" then
the answer
is almost certainly no.

But there are lots of things you can't do without relying on extensions to
the pthreads
implementation (e.g. garbage collection, reasonable cost reference counting,
etc.)

So my question was really: "Can I extend the pthreads
implementation/documentation such that
Thread.interrupt() is implementable in terms of pthread_cancel()?"  In that
case,
the answer is likely to be "yes".

It seems to me that this is a reasonable approach for getting the
functionality on Linux.
Java is likely to eventually be either the most important client of
pthreads, or certainly
one of the most important clients.  Adding minor extensions to make them
cooperate seems
more than reasonable.

It does mean that you won't get instantaneous support for this feature on
all platforms.
But at least you have a path to get there on each platform.

I haven't a clue whether, for example, the linux_threads implementation,
would actually
need to be changed.  Certainly more of its behavior would have to be exposed
to gcj.
(I implemented this once in a different context while I was working for SGI.
My recollection
is that in that case essentially no pthread code changes were required in
the end.)

Hans

-----Original Message-----
From: Tom Tromey [ mailto:tromey@cygnus.com ]
Sent: Tuesday, March 14, 2000 10:52 AM
To: Boehm, Hans
Cc: 'Miles Sabin'; java-discuss@sourceware.cygnus.com
Subject: RE: Thread.interrupt()

Hans> It seems to me that Thread.interrupt() should in fact be
Hans> implemented (on Posix platforms) using pthread_cancel, though it
Hans> may take some work on the pthreads side to make that fly.

I don't see how this can be done, because I don't see how you can stop
a cancellation in progress (eg, throwing an exception from a cleanup
handler is undefined behavior).  Bryce and I have been talking about
just implementing condition variables on our own for POSIX, since the
POSIX and Java models don't line up enough.  I'd love to be wrong
about this.

Tom

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14  5:52     ` Thread.interrupt() Jeff Sturm
@ 2000-03-14 11:02       ` Tom Tromey
  2000-04-01  0:00         ` Thread.interrupt() Tom Tromey
  2000-03-14 14:16       ` Thread.interrupt() Bryce McKinlay
  2000-04-01  0:00       ` Thread.interrupt() Jeff Sturm
  2 siblings, 1 reply; 51+ messages in thread
From: Tom Tromey @ 2000-03-14 11:02 UTC (permalink / raw)
  To: Jeff Sturm; +Cc: Kresten Krab Thorup, Bryce McKinlay, java-discuss

Jeff> Question: do the libgcj maintainers feel obligated to follow
Jeff> Sun's interpretation of the JLS?

That's a good question.  I think the basic answer is "yes".  We think
compatibility is good.

However, I don't interpret that to mean strict compliance to a
particular version of the JDK.  Nor do I interpret that to mean bug
compatibility with JDK.

This is a very tricky area, and about the best we can do is examine
things on a case-by-case basis.  Generally speaking there doesn't seem
to be a "right" approach, especially given that in some situations,
like this one, Sun is willing to change the spec to suit defects in
their implementation (or at least in their research).

Tom

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
  2000-03-14  9:57 Thread.interrupt() Boehm, Hans
@ 2000-03-14 10:52 ` Tom Tromey
  2000-04-01  0:00   ` Thread.interrupt() Tom Tromey
  2000-03-14 15:59 ` Thread.interrupt() Jesper Peterson
  2000-04-01  0:00 ` Thread.interrupt() Boehm, Hans
  2 siblings, 1 reply; 51+ messages in thread
From: Tom Tromey @ 2000-03-14 10:52 UTC (permalink / raw)
  To: Boehm, Hans; +Cc: 'Miles Sabin', java-discuss

Hans> It seems to me that there are a bunch of problems with leaving
Hans> out interruptable I/O:

I agree.  Also I don't see any text in the 1.3 online docs to indicate
that this is deprecated; depending on the bug parade seems suboptimal.

Hans> It seems to me that Thread.interrupt() should in fact be
Hans> implemented (on Posix platforms) using pthread_cancel, though it
Hans> may take some work on the pthreads side to make that fly.

I don't see how this can be done, because I don't see how you can stop
a cancellation in progress (eg, throwing an exception from a cleanup
handler is undefined behavior).  Bryce and I have been talking about
just implementing condition variables on our own for POSIX, since the
POSIX and Java models don't line up enough.  I'd love to be wrong
about this.

Tom

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
@ 2000-03-14  9:57 Boehm, Hans
  2000-03-14 10:52 ` Thread.interrupt() Tom Tromey
                   ` (2 more replies)
  0 siblings, 3 replies; 51+ messages in thread
From: Boehm, Hans @ 2000-03-14  9:57 UTC (permalink / raw)
  To: 'Miles Sabin', java-discuss

It seems to me that there are a bunch of problems with leaving out
interruptable
I/O:

- As Jeff and the Sun bug report point out, there doesn't seem to be a
portable alternative.

- The closest alternative, closing the descriptor, doesn't feel like
reasonable programming
practice.  If I want to stop a worker thread I created, it's not necessarily
my business to
know what file descriptor it's waiting on.  The "technique", if I understand
it correctly,
seems to be a gross violation of modularity.

- I view gcj's goal as providing a Java implementation that is particularly
interoperable
with C/C++.  In the Posix world, there is an approximate equivalent for
thread.interrupt:
pthread_cancel.  (Based on a quick look at the source, recent versins seem
to try to do the
right thing on Linux, in spite of the documentation.)  I think this makes it
highly
desirable that pthread_cancel should work on Java threads.  Once you accept
that, it seems
hard to believe that Thread.interrupt() can't do the right thing.  It seems
to me that
Thread.interrupt() should in fact be implemented (on Posix platforms) using
pthread_cancel,
though it may take some work on the pthreads side to make that fly.

Hans


-----Original Message-----
From: Miles Sabin [ mailto:msabin@cromwellmedia.co.uk ]
Sent: Tuesday, March 14, 2000 6:00 AM
To: java-discuss@sourceware.cygnus.com
Subject: RE: Thread.interrupt()


Jeff Sturm wrote,
> IOW, Sun crippled their API because Win32 doesn't handle 
> interruptable I/O portably.  Not a good policy.
>
> Since Java doesn't support read() with timeouts either, it is 
> easy to create a "stuck" thread that can never die.

The following posting of Doug Lea's on this topic from a while 
back on the advanced-java list is the best response to your
complaint ...

Doug Lea wrote,
> I think the consensus is that Interruptible I/O was a
> reasonable-looking notion that turned out to be a bad idea in
> practice. In fact, I hope it becomes deprecated before it is 
> fully implemented. (Currently, it is very incompletely 
> implemented, at least on Solaris and Win platforms.) The 
> fundamental problem is that there is rarely a reasonable 
> continuation action that can be taken if low-level I/O 
> interrupts.  Most Java programs use buffered or translated 
> I/O classes, which in turn rely on lower-level I/O classes. 
> But there is hardly ever a way for them to roll back or
> forward under a lower level exception. So the only recourse 
> is to abort.
>
> Given this (see http://gee.cs.oswego.edu/dl/cpj/cancel.html ), 
> usually the best way to implement cancellation in I/O is just 
> resource revocation -- asynchronously forcibly closing the 
> stream that the thread is operating on. This results in a 
> generic I/O exception, which can then be used to shut down a 
> thread. This works well (at least on Solaris 1.2. I don't 
> know about other platforms). To play it safe, and force 
> termination whether the thread is actually doing any I/O, you
> should normally do both stream.close() and Thread.interrupt
> ().

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: Thread.interrupt()
@ 2000-03-14  7:47 Miles Sabin
  2000-04-01  0:00 ` Thread.interrupt() Miles Sabin
  0 siblings, 1 reply; 51+ messages in thread
From: Miles Sabin @ 2000-03-14  7:47 UTC (permalink / raw)
  To: java-discuss

Jeff Sturm wrote,
> [snip: resource revocation as an alternative to interrupt()]
> That sounds like trading one set of underspecified behavior 
> for another.  I haven't tested myself this on any range of 
> platforms.

Perhaps, yes. However, I would expect any robust implementation
of a stream class to respond in the Right Way to closure.

> Some stream classes are virtual, like PipedReader.  It blocks 
> on object.wait().   Waking it up with an interrupt would be 
> easy enough. It can be made to respond to a close() as well.

It is in Sun's implementation (all the recent one's anyhow).
The alternative would be to leave either or both of the
producer/consumer threads permanently blocked ... if that
happened I'd call it a bug, independently of any issues around
interruption.

Cheers,


Miles

-- 
Miles Sabin                       Cromwell Media
Internet Systems Architect        5/6 Glenthorne Mews
+44 (0)20 8817 4030               London, W6 0LJ, England
msabin@cromwellmedia.com          http://www.cromwellmedia.com/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14  2:24   ` Thread.interrupt() Kresten Krab Thorup
  2000-03-14  3:26     ` Thread.interrupt() Bryce McKinlay
@ 2000-03-14  5:52     ` Jeff Sturm
  2000-03-14 11:02       ` Thread.interrupt() Tom Tromey
                         ` (2 more replies)
  2000-04-01  0:00     ` Thread.interrupt() Kresten Krab Thorup
  2 siblings, 3 replies; 51+ messages in thread
From: Jeff Sturm @ 2000-03-14  5:52 UTC (permalink / raw)
  To: Kresten Krab Thorup; +Cc: Bryce McKinlay, java-discuss

Kresten Krab Thorup wrote:
[...]
> As of today, the interruptable io has officially deprecated. We are not
> going to fix this bug. However, we leave the current implementation as
> it is for backward compatibility.
> 
> xxxxx@xxxxx 1999-09-12

IOW, Sun crippled their API because Win32 doesn't handle interruptable
I/O portably.  Not a good policy.

Since Java doesn't support read() with timeouts either, it is easy to
create a "stuck" thread that can never die.

Question: do the libgcj maintainers feel obligated to follow Sun's
interpretation of the JLS?

-- 
Jeff Sturm
jsturm@sigma6.com

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-14  2:24   ` Thread.interrupt() Kresten Krab Thorup
@ 2000-03-14  3:26     ` Bryce McKinlay
  2000-04-01  0:00       ` Thread.interrupt() Bryce McKinlay
  2000-03-14  5:52     ` Thread.interrupt() Jeff Sturm
  2000-04-01  0:00     ` Thread.interrupt() Kresten Krab Thorup
  2 siblings, 1 reply; 51+ messages in thread
From: Bryce McKinlay @ 2000-03-14  3:26 UTC (permalink / raw)
  To: Kresten Krab Thorup; +Cc: java-discuss

Thanks for the link. There is another, long discussion of the subject from
a Sun engineer at
http://developer.java.sun.com/developer/bugParade/bugs/4154947.html

Basically it appears that they deprecated it because it didn't work on
Win32. Interruptable I/O seems like it would be a nice feature to have,
but given that it is deprecated I don't think I'll bother to implement it
now.

regards

  [ bryce ]


Kresten Krab Thorup wrote:

> As of today, the interruptable io has officially deprecated. We are not
> going to fix this bug. However, we leave the current implementation as
> it is for backward compatibility.
>
> xxxxx@xxxxx 1999-09-12

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-03-13 13:33 ` Thread.interrupt() Bryce McKinlay
@ 2000-03-14  2:24   ` Kresten Krab Thorup
  2000-03-14  3:26     ` Thread.interrupt() Bryce McKinlay
                       ` (2 more replies)
  2000-04-01  0:00   ` Thread.interrupt() Bryce McKinlay
  1 sibling, 3 replies; 51+ messages in thread
From: Kresten Krab Thorup @ 2000-03-14  2:24 UTC (permalink / raw)
  To: Bryce McKinlay; +Cc: java-discuss

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 779 bytes --]

See:

http://developer.java.sun.com/developer/bugParade/bugs/4103109.html

The evaluation reads:

We believe Thread.interrupt to be no worse (and no better) than
Thread.stop at interrupting I/O in progress.  Unfortunately, neither of
these calls reliably breaks out of I/O waits.  On some platforms, it is
extremely difficult to implement the desired behavior.

xxxxx@xxxxx 1998-06-25

As of today, the interruptable io has officially deprecated. We are not
going to fix this bug. However, we leave the current implementation as
it is for backward compatibility.

xxxxx@xxxxx 1999-09-12


-- Kresten

Kresten Krab Thorup, Director of Research
Eastfork Object Space (EOS), Margrethepladsen 3, 8000  Ã…rhus C, Denmark
Tel: +45 8732 8787 / Fax: +45 8732 8788 / Mob: +45 2343 4626

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Thread.interrupt()
  2000-04-01  0:00 Thread.interrupt() Bryce McKinlay
@ 2000-03-13 13:33 ` Bryce McKinlay
  2000-03-14  2:24   ` Thread.interrupt() Kresten Krab Thorup
  2000-04-01  0:00   ` Thread.interrupt() Bryce McKinlay
  0 siblings, 2 replies; 51+ messages in thread
From: Bryce McKinlay @ 2000-03-13 13:33 UTC (permalink / raw)
  To: java-discuss

Bryce McKinlay wrote:

> Is there any online documentation where the semantics of
> thread.interrupt() are fairly precisely specified? It isn't mentioned in
> either the JLS or JVM spec, and the API documentation is a little bit...
> vague.

Specifically, I was under the impression that Thread.interrupt() should
interrupt a thread that is blocking on an I/O operation (Socket.read() etc)
- otherwise what is InterruptedIOException for? However, from reading posts
to Sun's java discussion forums [*], it appears that this is not the case,
at least for recent JDKs. Is it worth trying to implement this?

Also, regarding interaction between interrupt() and wait(): suppose we have
4 threads. Two of these (1&2) are blocked on wait() for the monitor "a".
Simultaniously, thread 3 calls a.notify() and thread 4 calls
thread1.interrupt(). My guess is that the correct behaviour is for EITHER
thread 1 to wake up normally, but also have its interrupt status flag set,
or for thread 2 to wake up normally and thread 1 to wake up with an
InterruptedException. Is this correct?

regards

  [ bryce ]

[*]:
http://forum2.java.sun.com/forum?14@@.787b6e5f
http://forum2.java.sun.com/forum?14@@.ee778af


^ permalink raw reply	[flat|nested] 51+ messages in thread

end of thread, other threads:[~2000-04-01  0:00 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-03-14  6:00 Thread.interrupt() Miles Sabin
2000-03-14  7:36 ` Thread.interrupt() Jeff Sturm
2000-03-14 10:58   ` Thread.interrupt() Tom Tromey
2000-04-01  0:00     ` Thread.interrupt() Tom Tromey
2000-04-01  0:00   ` Thread.interrupt() Jeff Sturm
2000-04-01  0:00 ` Thread.interrupt() Miles Sabin
2000-03-14  7:47 Thread.interrupt() Miles Sabin
2000-04-01  0:00 ` Thread.interrupt() Miles Sabin
2000-03-14  9:57 Thread.interrupt() Boehm, Hans
2000-03-14 10:52 ` Thread.interrupt() Tom Tromey
2000-04-01  0:00   ` Thread.interrupt() Tom Tromey
2000-03-14 15:59 ` Thread.interrupt() Jesper Peterson
2000-04-01  0:00   ` Thread.interrupt() Jesper Peterson
2000-04-01  0:00 ` Thread.interrupt() Boehm, Hans
2000-03-14 11:26 Thread.interrupt() Boehm, Hans
2000-04-01  0:00 ` Thread.interrupt() Boehm, Hans
2000-03-14 16:30 Thread.interrupt() Boehm, Hans
2000-03-14 17:17 ` Thread.interrupt() Jesper Peterson
2000-03-14 17:27   ` Thread.interrupt() Tom Tromey
2000-04-01  0:00     ` Thread.interrupt() Tom Tromey
2000-04-01  0:00   ` Thread.interrupt() Jesper Peterson
2000-04-01  0:00 ` Thread.interrupt() Boehm, Hans
2000-03-15  5:51 Thread.interrupt() Miles Sabin
2000-04-01  0:00 ` Thread.interrupt() Miles Sabin
2000-03-15 11:38 Thread.interrupt() Boehm, Hans
2000-04-01  0:00 ` Thread.interrupt() Boehm, Hans
2000-03-15 11:57 Thread.interrupt() Miles Sabin
2000-04-01  0:00 ` Thread.interrupt() Miles Sabin
2000-03-15 12:55 Thread.interrupt() Boehm, Hans
2000-04-01  0:00 ` Thread.interrupt() Boehm, Hans
2000-03-15 13:06 Thread.interrupt() Miles Sabin
2000-04-01  0:00 ` Thread.interrupt() Miles Sabin
2000-03-15 13:52 Thread.interrupt() Boehm, Hans
2000-04-01  0:00 ` Thread.interrupt() Boehm, Hans
2000-03-16  4:08 Thread.interrupt() Miles Sabin
2000-04-01  0:00 ` Thread.interrupt() Miles Sabin
2000-04-01  0:00 Thread.interrupt() Bryce McKinlay
2000-03-13 13:33 ` Thread.interrupt() Bryce McKinlay
2000-03-14  2:24   ` Thread.interrupt() Kresten Krab Thorup
2000-03-14  3:26     ` Thread.interrupt() Bryce McKinlay
2000-04-01  0:00       ` Thread.interrupt() Bryce McKinlay
2000-03-14  5:52     ` Thread.interrupt() Jeff Sturm
2000-03-14 11:02       ` Thread.interrupt() Tom Tromey
2000-04-01  0:00         ` Thread.interrupt() Tom Tromey
2000-03-14 14:16       ` Thread.interrupt() Bryce McKinlay
2000-03-14 16:09         ` Thread.interrupt() Godmar Back
2000-04-01  0:00           ` Thread.interrupt() Godmar Back
2000-04-01  0:00         ` Thread.interrupt() Bryce McKinlay
2000-04-01  0:00       ` Thread.interrupt() Jeff Sturm
2000-04-01  0:00     ` Thread.interrupt() Kresten Krab Thorup
2000-04-01  0:00   ` Thread.interrupt() Bryce McKinlay

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).