harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paulex Yang <paulex.y...@gmail.com>
Subject Re: [Fwd: [classlib][NIO|VMI]Interruptible channel implementation - how to interact with Thread?]
Date Fri, 16 Jun 2006 02:36:32 GMT
Archie,

Thank you for the explanation, I'm appreciated most of your suggestion, 
because mostly I planned to do the same thing as part of interruption 
and asynchronized close implementation. But actually the problem is how 
Thread can understand what the other thread is blocking on. Please see 
my comments inline:

Archie Cobbs wrote:
> Paulex Yang wrote:
>> Jimmy, Jing Lv wrote:
>>> Archie Cobbs wrote:
>>>> Paulex Yang wrote:
>>>>> Seems Thread's implementation must be aware of what operation it 
>>>>> is blocking on. So I propose the following solution:
>>>>
>>>> I don't think the VM or java.lang.Thread needs to be involved.
>>>> First of all, the code performing the blocking operation knows
>>>> what kind of operation it is, so when it wakes up abnormally it
>>>> can take the appropriate action. This code doesn't necessarily
>>>> reside in java.lang.Thread.
>>>>
>>>> In Classpath the java.nio stuff is all implemented in native
>>>> libraries without the VM or java.lang.Thread being specially
>>>> "aware" of anything. However, classlib's design may be different
>>>> enough to need it (I haven't studied it as much as you guys).
>>>>
>>>> E.g., the java.nio native code does invoke Thread.interrupt() and
>>>> Thread.interrupted(), but these are normal, API-specified methods.
>>>>
>>>> Might be worth taking a look for some design ideas.
>>>>
>>>
>>> Thanks Archie, it sounds interesting :).
>>> As I study few about Classpath, I still have a question here. As we 
>>> know, there are three states of "blocking" on a thread. One is 
>>> wait(), sleep() and so forth, thread class handle them itself, it is 
>>> easy to interrupt; and one is blocking on I/O, invoke 
>>> Thread.interrupt() may be not enough as it is blocked on a system 
>>> call, e.g., call read on socket may not return until it receive 
>>> something or it is closed. In this way, the Thread.interrupt should 
>>> know how to close the socket to perform the real interruption. The 
>>> question is: how can the thread know if it is blocked on wait() or 
>>> I/O operation currently? I think this is the reason why Paulex 
>>> require Thread to be involved. So I'm very interested in what does 
>>> Classpath do here to stop I/O operation without get involved?
>> Actually Thread.interrupt() is required to handle four different 
>> scenario:
>> 1. wait(), join(), etc, throw InterruptException
>> 2. blocking I/O, close the channel, and throw ClosedByInterruptException
>> 3. blocking select, wake up the selector
>> 4. none of above, just set the thread's interrupt status
>>
>> So if we don't involve Thread and want to implment scenario 2 and 3, 
>> we may find the situation is:
>> a. If Thread cannot judge scenario 2/3, so it may think they are both 
>> scenario 4, so Thread.interrupt() just set the interrupt status and 
>> do nothing else, the I/O operation is still blocking there, we cannot 
>> get it actually interrupted.
>> b. If Thread can find the thread is blocking somewhere, and it 
>> considers all blocking as scenario 1, so the InterruptException is 
>> thrown, but considering scenario c, Selector.select() should be waked 
>> up without exception, while our selector only has the end() executed 
>> in finally block like below, how does end() catch the thrown 
>> InterruptException and handle it silently?
>>
>> try {
>>     begin();
>>     // Perform blocking I/O operation here
>>     ...
>> } finally {
>>     end();
>> }
>> c. If Thread can magically find the thread is blocking on I/O or 
>> select, it may need to set the interrupt status, and make the blocked 
>> Java method return with some error, so that the end() can check them. 
>> Further, the Thread needs to know if this blocking I/O is 
>> "interruptible" in Java, for example, the ServerSocket.accept() and 
>> ServerSocketChannel.accept() probably uses same system call, but 
>> Thread should know ServerSocket cannot be interrupted while 
>> ServerSocketChannel can...I have no any idea how Thread can do this 
>> without interaction with NIO channels.
>>
>> So, Archie, I'm very interested in how Classpath handle this problem. 
>> Would you please help to give more details for it (if no legal concern)?
>
> To be honest I'm not sure how exactly it works, or even that it does 
> (I haven't
> played with the nio stuff at all).. I only know that Thread 
> implementations in
> Classpath don't have special stuff for NIO channels.
>
> Taking a look at Classpath...
>
> In Classpath, if select(2) returns EINTR, the select just returns 
> normally
> (with nothing selected) and then the code checks Thread.interrupted().
> If set, it closes and throws the exception as necessary.
Yes I noticed that select(2) on Linux has this good feature, but I 
cannot find similar way on Windows:(.
>
> Also, on UNIX at least, one thread may close a file descriptor that
> another thread is waiting on and the second thread will immediately
> wake up with an error. So that case is easy to handle.
Yes, that's what I tried to do in the InterruptAction which is given to 
Thread.setInterruptAction(). The problem here is not *how* to close the 
file descriptor, but is if thread B want to interrupt thread A, the B 
don't know *if* there are any file descriptor to be closed for A or 
*which* file descriptor to close.

Further, as I mentioned in situation c above, even Thread B can find 
Thread A is blocking on some I/O and can know the file descriptor, I'm 
not sure how it can know *whether* the I/O is interruptible in Java, for 
example, for ServerSocket and ServerSocketChannel which share same fd, 
if you invoke ServerSocketChannel.accept(), it is interruptible, but 
ServerSocket.accept() is not(at least on RI).
>
> So the only hard part is waking up the sleeping thread that you have
> interrupted. Once it wakes up, the rest can be handled in Java.
>
> A thread blocking on select() will get EINTR if a signal is received. 
> A thread
> can signal other threads (via native code) using pthread_kill(). So one
> approach would be for the VM to signal a thread with an otherwise ignored
> signal when that thread is interrupted. The only possibilities I see are:
>
> 1. Interrupt select(2) with a signal
> 2. select(2) listens on an additional "secret" file descriptor for 
> reading
>     and the VM writes a byte into it
This is actually what I did in Harmony-41 for Selector's wakeup() 
method, I open a Pipe and add it to Selector's keys set, write a byte to 
Pipe.SinkeChannel when wake up.
> 3. select(2) is called with a short timeout, and each time it returns
>     with timeout we check Thread.interrupted(), then try again.
>
> #1 is most efficient and simplest, but requires VM participation (not 
> much).
I'm afraid #1 may not workable in other platforms in Windows, although 
this is good feature for Linux. And even it works, the issue above still 
exists.
> #3 has the advantage of being VM indepdendent, but is less efficient.
>
> I think for now at least #3 is a viable alternative. A timeout like 
> 250ms would
> give a quick response time with minimal overhead.
The other problem is we may not have too many freedom to design the 
interruption and Async close implementation, because Java spec requires 
the related operation are encapsulated in AbstractInterruptibleChannel's 
begin()/end() method, which mark the start/end of some interruptible I/O 
operation, so that its subclass can get the capability easily by invoke 
the two methods following spec. And AbstractInterruptibleChannel is 
extensible to classlib users.
>
> -Archie
>
> __________________________________________________________________________ 
>
> Archie Cobbs      *        CTO, Awarix        *      
> http://www.awarix.com
>
> ---------------------------------------------------------------------
> Terms of use : http://incubator.apache.org/harmony/mailing.html
> To unsubscribe, e-mail: harmony-dev-unsubscribe@incubator.apache.org
> For additional commands, e-mail: harmony-dev-help@incubator.apache.org
>
>


-- 
Paulex Yang
China Software Development Lab
IBM



---------------------------------------------------------------------
Terms of use : http://incubator.apache.org/harmony/mailing.html
To unsubscribe, e-mail: harmony-dev-unsubscribe@incubator.apache.org
For additional commands, e-mail: harmony-dev-help@incubator.apache.org


Mime
View raw message