[kaffe] problems with thread and ServerSocket.close()
Jean-frederic Clere
jfclere at sinix.net
Wed Nov 2 14:03:17 PST 2005
Hi,
I have tried a small test program that runs correctly in Sun JVM but
hangs in kaffe:
By close() on a ServerSocket I expect to cause an exception in the
thread where I am doing the accept() om the same ServerSocket, but the
close() hangs until a new connection is openned.
Any hints why the close() does not provoque an exception in the accept().
Cheers
Jean-Frederic
PS: Find attached the java code I am using.
-------------- next part --------------
/*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* @version $Id: JFCtest.java 165001 2005-04-27 16:01:42Z jfclere $ */
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Vector;
public class JFCtest implements Runnable {
private ServerSocket server=null;
private Thread thread=null;
private boolean stopping=false;
private Vector handlers=null;
public static native void toto();
public JFCtest() {
super();
System.err.println("JFCtest: instance "+this.hashCode()+
" created");
this.handlers=new Vector();
}
protected void finalize() {
System.err.println("JFCtest: instance "+this.hashCode()+
" garbage collected");
}
/**
* init and destroy were added in jakarta-tomcat-daemon.
*/
public void init()
throws Exception {
System.err.println("JFCtest: instance "+this.hashCode()+
" init");
int port=1200;
/* Dump a message */
System.err.println("JFCtest: loading on port "+port);
this.server=new ServerSocket(port);
this.thread=new Thread(this);
}
public void start() {
/* Dump a message */
System.err.println("JFCtest: starting");
/* Start */
this.thread.start();
}
public void stop()
throws IOException, InterruptedException {
/* Dump a message */
System.err.println("JFCtest: stopping");
/* Close the ServerSocket. This will make our thread to terminate */
this.stopping=true;
// this.server.setSoTimeout(10);
System.err.println("JFCtest: stopping: before close");
// this.thread.interrupt();
this.server.close();
System.err.println("JFCtest: stopping: after close");
/* Wait for the main thread to exit and dump a message */
try {
this.thread.join(5000);
} catch (InterruptedException e) {
}
System.err.println("JFCtest: stopped");
}
public void destroy() {
System.err.println("JFCtest: instance "+this.hashCode()+
" destroy");
}
public void run() {
int number=0;
System.err.println("JFCtest: started acceptor loop");
try {
while(!this.stopping) {
Socket socket=this.server.accept();
Handler handler=new Handler(socket,this);
handler.setConnectionNumber(number++);
new Thread(handler).start();
}
} catch (IOException e) {
/* Don't dump any error message if we are stopping. A IOException
is generated when the ServerSocket is closed in stop() */
if (!this.stopping) e.printStackTrace(System.err);
e.printStackTrace(System.err);
}
/* Terminate all handlers that at this point are still open */
Enumeration openhandlers=this.handlers.elements();
while (openhandlers.hasMoreElements()) {
Handler handler=(Handler)openhandlers.nextElement();
System.err.println("JFCtest: dropping connection "+
handler.getConnectionNumber());
handler.close();
}
System.err.println("JFCtest: exiting acceptor loop");
}
protected void addHandler(Handler handler) {
synchronized (handler) {
this.handlers.add(handler);
}
}
protected void removeHandler(Handler handler) {
synchronized (handler) {
this.handlers.remove(handler);
}
}
public static class Handler implements Runnable {
private JFCtest parent=null;
private Socket socket=null;
private int number=0;
public Handler(Socket s, JFCtest p) {
super();
this.socket=s;
this.parent=p;
}
public void run() {
this.parent.addHandler(this);
System.err.println("JFCtest: connection "+this.number+
" opened from "+this.socket.getInetAddress());
try {
InputStream in=this.socket.getInputStream();
OutputStream out=this.socket.getOutputStream();
handle(in,out);
this.socket.close();
} catch (IOException e) {
e.printStackTrace(System.err);
}
System.err.println("JFCtest: connection "+this.number+
" closed");
this.parent.removeHandler(this);
}
public void close() {
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
public void setConnectionNumber(int number) {
this.number=number;
}
public int getConnectionNumber() {
return(this.number);
}
public void handle(InputStream in, OutputStream os) {
PrintStream out=null;
try {
out=new PrintStream(os, true, "US-ASCII");
} catch (UnsupportedEncodingException ex) {
out=new PrintStream(os);
}
while(true) {
try {
/* If we don't have data in the System InputStream, we want
to ask to the user for an option. */
if (in.available()==0) {
out.println();
out.println("Please select one of the following:");
out.println(" 1) Shutdown");
out.println(" 2) Disconnect");
out.print("Your choiche: ");
}
/* Read an option from the client */
int x=in.read();
switch (x) {
/* If the socket was closed, we simply return */
case -1:
return;
/* Attempt to shutdown */
case '1':
out.println("Attempting a shutdown...");
try {
this.parent.stop();
} catch (Exception e) {
out.println();
out.println("Can't shutdown now");
e.printStackTrace(out);
}
break;
/* Disconnect */
case '2':
out.println("Disconnecting...");
return;
/* Discard any carriage return / newline characters */
case '\r':
case '\n':
break;
/* We got something that we weren't supposed to get */
default:
out.println("Unknown option '"+(char)x+"'");
break;
}
/* If we get an IOException we return (disconnect) */
} catch (IOException e) {
System.err.println("JFCtest: IOException in "+
"connection "+
this.getConnectionNumber());
return;
}
}
}
}
public static void main(String[] args) throws Exception {
JFCtest mytest = new JFCtest();
mytest.init();
mytest.start();
}
}
More information about the kaffe
mailing list