Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Cancelling out of a blocking read operation  RSS feed

 
dave taubler
Ranch Hand
Posts: 132
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have what I presume is a common need here. I'm working on a desktop client application that opens a socket to talk to an HTTP server (this will probably always be Tomcat/servlets, but that shouldn't matter). The portion of code I'm concerned about looks something like this:

That all, of course, runs within a separate Thread. The "clientLine = in.readLine()" blocks that thread and waits for a response. Since this can take awhile, I want to give users the option of cancelling out of this network communication altogether (similar to browsers offering a "stop loading" button). I've implemented the usual method of stopping a thread many times; the thread is usually in a loop and on each iteration does a test which, if fails, indicates that the thread should exit the loop. However, in a blocking situation like this, I don't think that would work.

Does anyone have any ideas on how, in this case, I could pre-empt the network activity and cause it to exit?
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try closing the socket from another thread. That ought to throw a wrench in the reader's gears.

I had one of these situations using an HttpURLConnection to read and I couldn't get access to the underlying socket to close it. My main thread spawns the reader thread, does a wait for so many seconds, checks a readerIsDone flag. If it's not done I interrupt the reader (which does nothing at the time), throw an exception in the main thread and go on with life. The reader thread will eventually get past the read, check the interrupted flag and just exit the run() method. It's not real pretty but it works.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[Stan]: Try closing the socket from another thread. That ought to throw a wrench in the reader's gears.

Maybe. Or maybe the close() method will block too - I've seen both happen. I don't know what determines which happens - I assume it's probably a system-dependent thing.

Trying to get out of a blocking read like this can be a major problem using traditional IO. There's no guaranteed solution. This was a major reason for the introduction of the java.nio packages in JDK 1.4 Depending who you ask, the NIO is either Nonblocking IO or New IO. You can find various code examples here. Of course the error handling in most javaalmanac examples is pretty horrible, and should be replaced with something that, well, handles errors.
 
dave taubler
Ranch Hand
Posts: 132
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the advice from both of you. I'm taking a sort of hybrid approach. For now, when the user cancels out of the network connection, I set a flag and then use a new thread to close() the reader (that new thread does indeed get blocked until the reader itself unblocks, but since it's its own thread, the user can't tell). So that works.

But I will explore NIO--it's high time I did so, anyway--and implement a better overall solution later.
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!