--- old/corba/src/share/classes/com/sun/corba/se/impl/transport/CorbaResponseWaitingRoomImpl.java Tue Aug 14 17:22:03 2012 +++ new/corba/src/share/classes/com/sun/corba/se/impl/transport/CorbaResponseWaitingRoomImpl.java Tue Aug 14 17:22:03 2012 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,10 @@ package com.sun.corba.se.impl.transport; -import java.util.Hashtable; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; import org.omg.CORBA.CompletionStatus; import org.omg.CORBA.SystemException; @@ -68,7 +71,7 @@ private CorbaConnection connection; // Maps requestId to an OutCallDesc. - private Hashtable out_calls = null; // REVISIT - use int hastable/map + final private Map out_calls; public CorbaResponseWaitingRoomImpl(ORB orb, CorbaConnection connection) { @@ -76,7 +79,8 @@ wrapper = ORBUtilSystemException.get( orb, CORBALogDomains.RPC_TRANSPORT ) ; this.connection = connection; - out_calls = new Hashtable(); + out_calls = + Collections.synchronizedMap(new HashMap()); } //////////////////////////////////////////////////// @@ -139,7 +143,7 @@ return null; } - OutCallDesc call = (OutCallDesc)out_calls.get(requestId); + OutCallDesc call = out_calls.get(requestId); if (call == null) { throw wrapper.nullOutCall(CompletionStatus.COMPLETED_MAYBE); } @@ -197,7 +201,7 @@ LocateReplyOrReplyMessage header = (LocateReplyOrReplyMessage) inputObject.getMessageHeader(); Integer requestId = new Integer(header.getRequestId()); - OutCallDesc call = (OutCallDesc) out_calls.get(requestId); + OutCallDesc call = out_calls.get(requestId); if (orb.transportDebugFlag) { dprint(".responseReceived: id/" @@ -248,7 +252,6 @@ public int numberRegistered() { - // Note: Hashtable.size() is not synchronized return out_calls.size(); } @@ -264,29 +267,41 @@ dprint(".signalExceptionToAllWaiters: " + systemException); } - OutCallDesc call; - java.util.Enumeration e = out_calls.elements(); - while(e.hasMoreElements()) { - call = (OutCallDesc) e.nextElement(); + synchronized (out_calls) { + if (orb.transportDebugFlag) { + dprint(".signalExceptionToAllWaiters: out_calls size :" + + out_calls.size()); + } - synchronized(call.done){ - // anything waiting for BufferManagerRead's fragment queue - // needs to be cancelled - CorbaMessageMediator corbaMsgMediator = - (CorbaMessageMediator)call.messageMediator; - CDRInputObject inputObject = - (CDRInputObject)corbaMsgMediator.getInputObject(); - // IMPORTANT: If inputObject is null, then no need to tell - // BufferManagerRead to cancel request processing. - if (inputObject != null) { - BufferManagerReadStream bufferManager = - (BufferManagerReadStream)inputObject.getBufferManager(); - int requestId = corbaMsgMediator.getRequestId(); - bufferManager.cancelProcessing(requestId); + for (OutCallDesc call : out_calls.values()) { + if (orb.transportDebugFlag) { + dprint(".signalExceptionToAllWaiters: signaling " + + call); } - call.inputObject = null; - call.exception = systemException; - call.done.notify(); + synchronized(call.done) { + try { + // anything waiting for BufferManagerRead's fragment queue + // needs to be cancelled + CorbaMessageMediator corbaMsgMediator = + (CorbaMessageMediator)call.messageMediator; + CDRInputObject inputObject = + (CDRInputObject)corbaMsgMediator.getInputObject(); + // IMPORTANT: If inputObject is null, then no need to tell + // BufferManagerRead to cancel request processing. + if (inputObject != null) { + BufferManagerReadStream bufferManager = + (BufferManagerReadStream)inputObject.getBufferManager(); + int requestId = corbaMsgMediator.getRequestId(); + bufferManager.cancelProcessing(requestId); + } + } catch (Exception e) { + } finally { + // attempt to wake up waiting threads in all cases + call.inputObject = null; + call.exception = systemException; + call.done.notifyAll(); + } + } } } } @@ -294,7 +309,7 @@ public MessageMediator getMessageMediator(int requestId) { Integer id = new Integer(requestId); - OutCallDesc call = (OutCallDesc) out_calls.get(id); + OutCallDesc call = out_calls.get(id); if (call == null) { // This can happen when getting early reply fragments for a // request which has completed (e.g., client marshaling error). --- old/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java Tue Aug 14 17:22:04 2012 +++ new/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java Tue Aug 14 17:22:04 2012 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1521,7 +1521,7 @@ // connection and give them the SystemException; responseWaitingRoom.signalExceptionToAllWaiters(systemException); - + } finally { if (contactInfo != null) { ((OutboundConnectionCache)getConnectionCache()).remove(contactInfo); } else if (acceptor != null) { @@ -1542,7 +1542,6 @@ writeUnlock(); - } finally { if (orb.transportDebugFlag) { dprint(".purgeCalls<-: " + minor_code + "/" + die + "/" + lockHeld --- old/jdk/test/Makefile Tue Aug 14 17:22:07 2012 +++ new/jdk/test/Makefile Tue Aug 14 17:22:06 2012 @@ -507,7 +507,8 @@ JDK_DEFAULT_TARGETS += jdk_misc jdk_misc: $(call TestDirs, \ demo/jvmti demo/zipfs javax/naming javax/script \ - javax/smartcardio com/sun/jndi com/sun/xml sun/misc) + javax/smartcardio com/sun/jndi com/sun/xml \ + com/sun/corba sun/misc) $(call RunAgentvmBatch) # Stable agentvm testruns (minus items from PROBLEM_LIST) --- /dev/null Tue Aug 14 17:22:09 2012 +++ new/jdk/test/com/sun/corba/cachedSocket/7056731.sh Tue Aug 14 17:22:08 2012 @@ -0,0 +1,119 @@ +# +# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# +# @test +# @bug 7056731 +# @summary Race condition in CORBA code causes re-use of ABORTed connections +# +# @run shell 7056731.sh +# + +OS=`uname -s` +case "$OS" in + SunOS | Linux | Darwin ) + PS=":" + FS="/" + ;; + Windows* | CYGWIN* ) + PS=";" + FS="\\" + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; +esac + +if [ "${TESTJAVA}" = "" ] ; then + echo "TESTJAVA not set. Test cannot execute. Failed." + exit 1 +fi + +JAVA="${TESTJAVA}${FS}bin${FS}java" +PORT=1052 +cp -r ${TESTSRC}${FS}*.java ${TESTSRC}${FS}Hello.idl . +echo "Testing...please wait" + +${TESTJAVA}${FS}bin${FS}idlj -fall Hello.idl +${TESTJAVA}${FS}bin${FS}javac *.java HelloApp/*.java + +echo "starting orbd" +${TESTJAVA}${FS}bin${FS}orbd -ORBInitialPort $PORT -ORBInitialHost localhost & +ORB_PROC=$! +sleep 2 #give orbd time to start +echo "started orb" +echo "starting server" +${TESTJAVA}${FS}bin${FS}java -cp . HelloServer -ORBInitialPort $PORT -ORBInitialHost localhost & +SERVER_PROC=$! +sleep 2 #give server time to start +echo "started server" +echo "starting client (debug mode)" +${TESTJAVA}${FS}bin${FS}java -cp . -agentlib:jdwp=transport=dt_socket,server=y,address=8000 HelloClient -ORBInitialPort $PORT -ORBInitialHost localhost > client.$$ 2>&1 & +JVM_PROC=$! +sleep 2 #give jvm/debugger/client time to start + +echo "started client (debug mode)" +echo "starting debugger and issuing commands" +(sleep 2; +echo "stop in com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.unregisterWaiter"; +sleep 2; +echo "run"; +sleep 2; +echo "cont"; +sleep 2; +echo "cont"; +sleep 2; +echo "cont"; +sleep 2; +echo "suspend 1"; +sleep 2; +kill -9 $SERVER_PROC &> /dev/null; +sleep 2; +echo "cont"; +sleep 2; +echo "thread 1" +sleep 2; +echo "clear com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.unregisterWaiter" +sleep 2; +echo "resume 1"; +)| ${TESTJAVA}${FS}bin${FS}jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8000 + +sleep 5 # give time for Client to throw exception + +# JVM_PROC should have exited but just in case, include it. +kill -9 $ORB_PROC $JVM_PROC + +grep "ORBUtilSystemException.writeErrorSend" client.$$ +result=$? +if [ $result -eq 0 ] +then + echo "Failed" + exitCode=1; +else + echo "Passed" + exitCode=0 +fi + +rm -rf out.$$ client.$$ +exit ${exitCode} --- /dev/null Tue Aug 14 17:22:11 2012 +++ new/jdk/test/com/sun/corba/cachedSocket/Hello.idl Tue Aug 14 17:22:10 2012 @@ -0,0 +1,8 @@ +module HelloApp +{ + interface Hello + { + string sayHello(); + oneway void shutdown(); + }; +}; --- /dev/null Tue Aug 14 17:22:14 2012 +++ new/jdk/test/com/sun/corba/cachedSocket/HelloClient.java Tue Aug 14 17:22:13 2012 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import HelloApp.*; +import org.omg.CosNaming.*; +import org.omg.CosNaming.NamingContextPackage.*; +import org.omg.CORBA.*; + +public class HelloClient +{ + static Hello helloImpl; + + public static void main(String args[]) + { + try{ + // create and initialize the ORB + ORB orb = ORB.init(args, null); + + // get the root naming context + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + // Use NamingContextExt instead of NamingContext. This is + // part of the Interoperable naming Service. + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + + // resolve the Object Reference in Naming + String name = "Hello"; + helloImpl = HelloHelper.narrow(ncRef.resolve_str(name)); + + System.out.println("Obtained a handle on server object: " + helloImpl); + for (int i = 0; i < 2; i++) { + try { + System.out.println(helloImpl.sayHello()); + } catch (Exception e) { + System.out.println("Exception: " + e.getMessage()); + e.printStackTrace(); + } + Thread.sleep(2000); + } + + } catch (Exception e) { + System.out.println("ERROR : " + e) ; + e.printStackTrace(System.out); + } + } + +} --- /dev/null Tue Aug 14 17:22:16 2012 +++ new/jdk/test/com/sun/corba/cachedSocket/HelloServer.java Tue Aug 14 17:22:15 2012 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import HelloApp.*; +import org.omg.CosNaming.*; +import org.omg.CosNaming.NamingContextPackage.*; +import org.omg.CORBA.*; +import org.omg.PortableServer.*; +import org.omg.PortableServer.POA; + +import java.util.Properties; + +class HelloImpl extends HelloPOA { + private ORB orb; + + public void setORB(ORB orb_val) { + orb = orb_val; + } + + // implement sayHello() method + public String sayHello() { + return "\nHello world !!\n"; + } + + // implement shutdown() method + public void shutdown() { + orb.shutdown(false); + } +} + + +public class HelloServer { + + public static void main(String args[]) { + try{ + // create and initialize the ORB + ORB orb = ORB.init(args, null); + + // get reference to rootpoa & activate the POAManager + POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); + rootpoa.the_POAManager().activate(); + + // create servant and register it with the ORB + HelloImpl helloImpl = new HelloImpl(); + helloImpl.setORB(orb); + + // get object reference from the servant + org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloImpl); + Hello href = HelloHelper.narrow(ref); + + // get the root naming context + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + // Use NamingContextExt which is part of the Interoperable + // Naming Service (INS) specification. + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + + // bind the Object Reference in Naming + String name = "Hello"; + NameComponent path[] = ncRef.to_name( name ); + ncRef.rebind(path, href); + + System.out.println("HelloServer ready and waiting ..."); + + // wait for invocations from clients + while (true) { + orb.run(); + } + } catch (Exception e) { + System.out.println("ERROR: " + e); + e.printStackTrace(System.out); + } + + System.out.println("HelloServer Exiting ..."); + + } +} +