* CORBA objects that exist on the same virtual machine and only are connected
to another ORB are now accessed directly and no longer via network. It is
the same feature that RMI implementation provides. These faster calls should
be completely transparent, as the parameters are cloned, where required.
Currently the direct calls are only possible for the non-deprecated objects
that are connected to the ORB via POA plus the GNU Classpath built in
naming service, regardless how it is connected.

2006-09-05  Audrius Meskauskas  <[EMAIL PROTECTED]>

   * gnu/CORBA/CollocatedOrbs.java,
   gnu/CORBA/SafeForDirectCalls.java: New files.
   * gnu/CORBA/NamingService/Binding_iterator_impl.java:
   Implement gnu.CORBA.SafeForDirectCalls.
   * gnu/CORBA/NamingService/Ext.java: Likewise.
   * gnu/CORBA/NamingService/TransientContext.java: Likewise.
   * gnu/CORBA/OrbFunctional.java (createIor):Cache the address
   of the local host. (ior_to_object): Return the local object
   where possible. (run): Register/unregister this ORB.
* gnu/CORBA/Poa/LocalRequest.java (v_invoke): Call gnuPOA.checkDiscarding. * gnu/CORBA/Poa/gnuPOA.java (checkDiscarding): Made package private.
   * gnu/CORBA/Poa/gnuServantObject.java (noRetain): New field.
   (constructors): Initialize noRetain. (_invoke): Drop servant
   if noRetain is true. (getHandler): Always seach for the new servant
   if noRetain is true.
   * gnu/CORBA/SimpleDelegate.java (create_request): Implemented.
   * NEWS: Added note about the new feature.
### Eclipse Workspace Patch 1.0
#P classpath
Index: gnu/CORBA/NamingService/TransientContext.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/CORBA/NamingService/TransientContext.java,v
retrieving revision 1.3
diff -u -r1.3 TransientContext.java
--- gnu/CORBA/NamingService/TransientContext.java	14 Feb 2006 15:32:27 -0000	1.3
+++ gnu/CORBA/NamingService/TransientContext.java	5 Sep 2006 21:01:52 -0000
@@ -54,6 +54,8 @@
 import org.omg.CosNaming.NamingContextPackage.NotFoundReason;
 import org.omg.CosNaming._NamingContextImplBase;
 
+import gnu.CORBA.SafeForDirectCalls;
+
 import java.util.Iterator;
 import java.util.Map;
 
@@ -69,7 +71,7 @@
  */
 public class TransientContext
   extends _NamingContextImplBase
-  implements NamingContext, NamingContextOperations
+  implements NamingContext, NamingContextOperations, SafeForDirectCalls
 {
   /**
    * Use serial version UID for interoperability.
Index: gnu/CORBA/NamingService/Ext.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/CORBA/NamingService/Ext.java,v
retrieving revision 1.3
diff -u -r1.3 Ext.java
--- gnu/CORBA/NamingService/Ext.java	28 Oct 2005 14:05:21 -0000	1.3
+++ gnu/CORBA/NamingService/Ext.java	5 Sep 2006 21:01:52 -0000
@@ -1,5 +1,5 @@
 /* TransientContextExt.java --
-   Copyright (C) 2005 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -38,6 +38,8 @@
 
 package gnu.CORBA.NamingService;
 
+import gnu.CORBA.SafeForDirectCalls;
+
 import org.omg.CORBA.NO_IMPLEMENT;
 import org.omg.CORBA.Object;
 import org.omg.CORBA.portable.Delegate;
@@ -61,7 +63,7 @@
  * @author Audrius Meskauskas, Lithuania ([EMAIL PROTECTED])
  */
 public class Ext
-  extends _NamingContextExtImplBase
+  extends _NamingContextExtImplBase implements SafeForDirectCalls
 {
   /**
    * The older version of the naming context, where all relevant calls
Index: gnu/CORBA/NamingService/Binding_iterator_impl.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/CORBA/NamingService/Binding_iterator_impl.java,v
retrieving revision 1.2
diff -u -r1.2 Binding_iterator_impl.java
--- gnu/CORBA/NamingService/Binding_iterator_impl.java	2 Jul 2005 20:32:09 -0000	1.2
+++ gnu/CORBA/NamingService/Binding_iterator_impl.java	5 Sep 2006 21:01:50 -0000
@@ -1,5 +1,5 @@
 /* Binding_iterator.java --
-   Copyright (C) 2005 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -38,6 +38,8 @@
 
 package gnu.CORBA.NamingService;
 
+import gnu.CORBA.SafeForDirectCalls;
+
 import org.omg.CosNaming.Binding;
 import org.omg.CosNaming.BindingHolder;
 import org.omg.CosNaming.BindingListHolder;
@@ -51,7 +53,7 @@
  * @author Audrius Meskauskas, Lithuania ([EMAIL PROTECTED])
  */
 public class Binding_iterator_impl
-  extends _BindingIteratorImplBase
+  extends _BindingIteratorImplBase implements SafeForDirectCalls
 {
   /**
    * The value, returned by the [EMAIL PROTECTED] #next_one} when there
Index: NEWS
===================================================================
RCS file: /sources/classpath/classpath/NEWS,v
retrieving revision 1.165
diff -u -r1.165 NEWS
--- NEWS	21 Aug 2006 04:46:35 -0000	1.165
+++ NEWS	5 Sep 2006 21:01:45 -0000
@@ -1,5 +1,11 @@
 New in release 0.93 (UNRELEASED)
 
+* CORBA objects that exist on the same virtual machine and only are connected
+  to another ORB are now accessed directly and no longer via network. It is
+  the same feature that RMI implementation provides. These faster calls should
+  be completely transparent, as the parameters are cloned, where required. 
+  Currently the direct calls are only possible for the non-deprecated objects
+  that are connected to the ORB via POA.
 * The 'javah' tool has been added.  It requires the ASM library
   (see asm.objectweb.org); it can be enabled with the --with-asm
   option to configure
Index: gnu/CORBA/Poa/gnuServantObject.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/CORBA/Poa/gnuServantObject.java,v
retrieving revision 1.8
diff -u -r1.8 gnuServantObject.java
--- gnu/CORBA/Poa/gnuServantObject.java	28 Oct 2005 14:05:22 -0000	1.8
+++ gnu/CORBA/Poa/gnuServantObject.java	5 Sep 2006 21:01:58 -0000
@@ -129,6 +129,12 @@
    * ids are requested from the servant.
    */
   public final String[] repository_ids;
+  
+  /**
+   * True indicates that the NO_RETAIN policy applies for the servant.
+   * The servant must be discarded after the each call.
+   */
+  boolean noRetain;
 
   /**
    * Create an object with no connected servant. The servant must be set later.
@@ -147,6 +153,8 @@
     manager = a_poa.the_POAManager();
     poa = a_poa;
     orb = an_orb;
+    
+    noRetain = poa.applies(ServantRetentionPolicyValue.NON_RETAIN);    
   }
   
   /**
@@ -182,6 +190,8 @@
       }
     repository_ids = null;
     orb = an_orb;
+    
+    noRetain = poa != null && poa.applies(ServantRetentionPolicyValue.NON_RETAIN);
   }
 
   /**
@@ -222,7 +232,7 @@
     boolean forwarding_allowed
   ) throws gnuForwardRequest
   {
-    if (servant != null)
+    if (servant != null && !noRetain)
       {
         return servantToHandler(servant);
       }
@@ -641,13 +651,14 @@
                     poa.servant_locator.postinvoke(Id, poa, method,
                       cookie.value, servant
                     );
-                    servant = null;
                   }
               }
           }
         finally
           {
             orb.currents.remove(Thread.currentThread());
+            if (noRetain)
+              servant = null;
           }
       }
     catch (ForwardRequest fex)
Index: gnu/CORBA/Poa/gnuPOA.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/CORBA/Poa/gnuPOA.java,v
retrieving revision 1.6
diff -u -r1.6 gnuPOA.java
--- gnu/CORBA/Poa/gnuPOA.java	31 Dec 2005 17:59:07 -0000	1.6
+++ gnu/CORBA/Poa/gnuPOA.java	5 Sep 2006 21:01:57 -0000
@@ -1582,7 +1582,7 @@
    *
    * @throws TRANSIENT if the POA is in discarding mode.
    */
-  private void checkDiscarding()
+  void checkDiscarding()
                         throws TRANSIENT
   {
     if (m_manager.get_state() == State.DISCARDING)
Index: gnu/CORBA/Poa/LocalRequest.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/CORBA/Poa/LocalRequest.java,v
retrieving revision 1.6
diff -u -r1.6 LocalRequest.java
--- gnu/CORBA/Poa/LocalRequest.java	28 Oct 2005 14:05:21 -0000	1.6
+++ gnu/CORBA/Poa/LocalRequest.java	5 Sep 2006 21:01:54 -0000
@@ -193,11 +193,14 @@
   /**
    * Make an invocation and return a stream from where the results can be read.
    *
-   * @param the invoke handler (can be null, then it is obtained self
+   * @param handler the invoke handler (can be null, then it is obtained self
    * dependently).
    */
   public org.omg.CORBA.portable.InputStream v_invoke(InvokeHandler handler)
   {
+    // Check maybe POA is in the discarding mode (will throw TRANSIENT if it is).
+    poa.checkDiscarding();  
+    
     // Local request must be intercepted both by server and request
     // interceptors.
     boolean s_intercept = false;
@@ -246,7 +249,7 @@
 
             s_interceptor.receive_request_service_contexts(s_info);
           }
-
+        
         if (handler == null)
           {
             handler = object.getHandler(operation(), cookie, false);
Index: gnu/CORBA/SimpleDelegate.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/CORBA/SimpleDelegate.java,v
retrieving revision 1.2
diff -u -r1.2 SimpleDelegate.java
--- gnu/CORBA/SimpleDelegate.java	6 Nov 2005 13:26:24 -0000	1.2
+++ gnu/CORBA/SimpleDelegate.java	5 Sep 2006 21:01:50 -0000
@@ -98,22 +98,31 @@
   }
 
   /**
-   * Not implemented.
-   *
-   * @throws NO_IMPLEMENT, always.
+   * Create the request for the local call
    */
   public Request create_request(org.omg.CORBA.Object target, Context context,
                                 String operation, NVList parameters,
                                 NamedValue returns
                                )
   {
-    throw new NO_IMPLEMENT();
+    if (orb instanceof OrbFunctional)
+      {
+        ((OrbFunctional) orb).ensureRunning();
+      }
+    gnuRequest g = new gnuRequest();
+    g.setORB(orb);
+    g.setOperation(operation);
+    g.setIor(ior);
+    g.m_target = target;
+    g.ctx(context);
+    g.set_args(parameters);
+    if (returns != null)
+      g.set_result(returns);
+    return g;    
   }
 
   /**
-   * Not implemented.
-   *
-   * @throws NO_IMPLEMENT, always.
+   * Create the request for the local call.
    */
   public Request create_request(org.omg.CORBA.Object target, Context context,
                                 String operation, NVList parameters,
@@ -121,7 +130,22 @@
                                 ContextList ctx_list
                                )
   {
-    throw new NO_IMPLEMENT();
+    if (orb instanceof OrbFunctional)
+      {
+        ((OrbFunctional) orb).ensureRunning();
+      }
+    gnuRequest g = new gnuRequest();
+    g.setORB(orb);
+    g.setOperation(operation);
+    g.setIor(ior);
+    g.m_target = target;
+    g.ctx(context);
+    g.set_args(parameters);
+    g.set_exceptions(exceptions);
+    g.set_context_list(ctx_list);
+    if (returns != null)
+      g.set_result(returns);
+    return g;
   }
 
   /**
Index: gnu/CORBA/OrbFunctional.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/CORBA/OrbFunctional.java,v
retrieving revision 1.5
diff -u -r1.5 OrbFunctional.java
--- gnu/CORBA/OrbFunctional.java	7 Aug 2006 01:04:15 -0000	1.5
+++ gnu/CORBA/OrbFunctional.java	5 Sep 2006 21:01:50 -0000
@@ -938,48 +938,55 @@
 
   /**
    * Start the ORBs main working cycle (receive invocation - invoke on the local
-   * object - send response - wait for another invocation).
-   *
-   * The method only returns after calling [EMAIL PROTECTED] #shutdown(boolean)}.
+   * object - send response - wait for another invocation). The method only
+   * returns after calling [EMAIL PROTECTED] #shutdown(boolean)}.
    */
   public void run()
   {
-    running = true;
-
-    // Instantiate the port server for each socket.
-    Iterator iter = connected_objects.entrySet().iterator();
-    Map.Entry m;
-    Connected_objects.cObject obj;
-
-    while (iter.hasNext())
+    CollocatedOrbs.registerOrb(this);
+    try
       {
-        m = (Map.Entry) iter.next();
-        obj = (Connected_objects.cObject) m.getValue();
+        running = true;
 
-        portServer subserver;
+        // Instantiate the port server for each socket.
+        Iterator iter = connected_objects.entrySet().iterator();
+        Map.Entry m;
+        Connected_objects.cObject obj;
 
-        if (obj.identity == null)
-          {
-            subserver = new portServer(obj.port);
-            portServers.add(subserver);
-          }
-        else
-          subserver = (portServer) identities.get(obj.identity);
-        
-        if (!subserver.isAlive())
+        while (iter.hasNext())
           {
-            // Reuse the current thread for the last portServer.
-            if (!iter.hasNext())
+            m = (Map.Entry) iter.next();
+            obj = (Connected_objects.cObject) m.getValue();
+
+            portServer subserver;
+
+            if (obj.identity == null)
               {
-                // Discard the iterator, eliminating lock checks.
-                iter = null;
-                subserver.run();
-                return;
+                subserver = new portServer(obj.port);
+                portServers.add(subserver);
               }
             else
-              subserver.start();
+              subserver = (portServer) identities.get(obj.identity);
+
+            if (! subserver.isAlive())
+              {
+                // Reuse the current thread for the last portServer.
+                if (! iter.hasNext())
+                  {
+                    // Discard the iterator, eliminating lock checks.
+                    iter = null;
+                    subserver.run();
+                    return;
+                  }
+                else
+                  subserver.start();
+              }
           }
       }
+    finally
+      {
+        CollocatedOrbs.unregisterOrb(this);
+      }
   }
   
   /**
@@ -1051,22 +1058,26 @@
     org.omg.CORBA.Object object = find_local_object(ior);
     if (object == null)
       {
-        ObjectImpl impl = StubLocator.search(this, ior);
-        try
+        // Check maybe the local object on another ORB, but same VM.
+        object = CollocatedOrbs.searchLocalObject(ior);
+        if (object == null)
           {
-            if (impl._get_delegate() == null)
-              impl._set_delegate(new IorDelegate(this, ior));
-          }
-        catch (BAD_OPERATION ex)
-          {
-            // Some colaborants may throw this exception
-            // in response to the attempt to get the unset delegate.
-            impl._set_delegate(new IorDelegate(this, ior));
-          }
+            // Surely remote object.
+            ObjectImpl impl = StubLocator.search(this, ior);
+            try
+              {
+                if (impl._get_delegate() == null)
+                  impl._set_delegate(new IorDelegate(this, ior));
+              }
+            catch (BAD_OPERATION ex)
+              {
+                // Some colaborants may throw this exception
+                // in response to the attempt to get the unset delegate.
+                impl._set_delegate(new IorDelegate(this, ior));
+              }
 
-        object = impl;
-        // TODO remove commented out code below.
-        // connected_objects.add(ior.key, impl, ior.Internet.port, null);
+            object = impl;
+          }
       }
     return object;
   }
@@ -1239,15 +1250,10 @@
       }
     if (ior.Id == null)
       ior.Id = ref.object.getClass().getName();
-    try
-      {
-        ior.Internet.host = InetAddress.getLocalHost().getHostAddress();
-        ior.Internet.port = ref.port;
-      }
-    catch (UnknownHostException ex)
-      {
-        throw new BAD_OPERATION("Cannot resolve the local host address");
-      }
+
+    ior.Internet.host = CollocatedOrbs.localHost;
+    ior.Internet.port = ref.port;
+
     return ior;
   }
 
Index: gnu/CORBA/CollocatedOrbs.java
===================================================================
RCS file: gnu/CORBA/CollocatedOrbs.java
diff -N gnu/CORBA/CollocatedOrbs.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnu/CORBA/CollocatedOrbs.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,164 @@
+/* CollocatedOrbs.java -- Handles collocations
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.CORBA;
+
+import gnu.CORBA.Poa.gnuServantObject;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+
+import org.omg.CORBA.LocalObject;
+import org.omg.CORBA.portable.Delegate;
+import org.omg.CORBA.portable.ObjectImpl;
+
+/**
+ * This class provides support for the direct method invocations without
+ * involving the network in the case when both ORBs run on the same java
+ * virtual machine. Special attention is only needed when call is made
+ * between two independent ORBs, instantiated via ORB.init. The call to the
+ * object, obtained via IOR reference from the ORB where it was locally
+ * connected is always local anyway.
+ * 
+ * For security reasons it may be sensible to keep this class and all support
+ * package private.
+ * 
+ * @author Audrius Meskauskas
+ */
+class CollocatedOrbs
+{
+  /**
+   * This field is used in automated Classpath specific testing to disable
+   * the direct calls. 
+   */
+  static boolean DIRECT_CALLS_ALLOWED = true;
+  
+   /**
+    * Containts the references of the all running GNU Classpath ORBs in the
+    * local virtual machine. GNU Classpath ORBs register themselves here when
+    * created and unregister when either ORB.destroy is called or in the 
+    * finalizer.
+    */
+   private static ArrayList orbs = new ArrayList();
+   
+   /**
+    * The address of the local host.
+    */
+   static String localHost;
+   
+   static
+    {
+      try
+        {
+          localHost = InetAddress.getLocalHost().getHostAddress();
+        }
+      catch (UnknownHostException ex)
+        {
+          throw new InternalError("Local host is not accessible:" + ex);
+        }
+    }
+   
+   /**
+     * Register the new ORB
+     * 
+     * @param orb the orb to register
+     */
+  static void registerOrb(OrbFunctional orb)
+  {
+    if (DIRECT_CALLS_ALLOWED)
+      synchronized (orbs)
+        {
+          assert ! orbs.contains(orb);
+          orbs.add(orb);
+        }
+  }
+  
+   /**
+     * Unregister the ORB. The ORB will no longer be reacheable locally but may
+     * be reacheable via network as if it would be remote.
+     * 
+     * @param orb the orb to unregister
+     */
+  static void unregisterOrb(OrbFunctional orb)
+  {
+    if (DIRECT_CALLS_ALLOWED)
+      synchronized (orbs)
+        {
+          assert orbs.contains(orb);
+          orbs.remove(orb);
+        }
+  }
+  
+  /**
+   * Search the possibly local object. If the IOR is not local or none of the
+   * found ORBs of this virtual machine knows about it, null is returned.
+   * 
+   * @param ior the IOR to search
+   * @return the found local CORBA object or null in not found.
+   */
+  static org.omg.CORBA.Object searchLocalObject(IOR ior)
+  {
+    if (! DIRECT_CALLS_ALLOWED && ! ior.Internet.host.equals(localHost))
+      return null;
+
+    synchronized (orbs)
+      {
+        OrbFunctional orb;
+        org.omg.CORBA.Object object;
+        for (int i = 0; i < orbs.size(); i++)
+          {
+            orb = (OrbFunctional) orbs.get(i);
+            object = orb.find_connected_object(ior.key, ior.Internet.port);
+            if (object != null)
+              {
+                if (object instanceof SafeForDirectCalls)
+                  {
+                    return object;
+                  }
+                else if (object instanceof gnuServantObject)
+                  {
+                    return object;
+                  }
+              }
+          }
+      }
+    return null;
+  }
+  
+}
Index: gnu/CORBA/SafeForDirectCalls.java
===================================================================
RCS file: gnu/CORBA/SafeForDirectCalls.java
diff -N gnu/CORBA/SafeForDirectCalls.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnu/CORBA/SafeForDirectCalls.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,50 @@
+/* SafeForDirectCalls.java -- FIXME: briefly describe file purpose
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.CORBA;
+
+/**
+ * This interface marks that the object does not modify the passed read only
+ * parameters and hence, if it is local, it is safe to call the methods
+ * directly, without cloning such parameters. Otherwise such parameters should
+ * be cloned.
+ */
+public interface SafeForDirectCalls
+{
+
+}

Reply via email to