[jboss-remoting-commits] JBoss Remoting SVN: r5569 - in remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3: spi and 1 other directory.

jboss-remoting-commits at lists.jboss.org jboss-remoting-commits at lists.jboss.org
Fri Oct 23 18:24:45 EDT 2009


Author: david.lloyd at jboss.com
Date: 2009-10-23 18:24:45 -0400 (Fri, 23 Oct 2009)
New Revision: 5569

Added:
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/BasicMarshallingProtocol.java
Modified:
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CopyOnWriteHashMap.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/MarshallingProtocol.java
Log:
Simplify service registration internals; add basic impl of MarshallingProtocol; add config options to marshalling configuration

Added: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/BasicMarshallingProtocol.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/BasicMarshallingProtocol.java	                        (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/BasicMarshallingProtocol.java	2009-10-23 22:24:45 UTC (rev 5569)
@@ -0,0 +1,122 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.remoting3;
+
+import org.jboss.remoting3.spi.MarshallingProtocol;
+import org.jboss.marshalling.Unmarshaller;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.MarshallerFactory;
+import org.jboss.marshalling.MarshallingConfiguration;
+import org.jboss.marshalling.Marshalling;
+import org.jboss.marshalling.reflect.SunReflectiveCreator;
+import org.jboss.xnio.Pool;
+import org.jboss.xnio.OptionMap;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.io.IOException;
+
+/**
+ * A marshalling protocol which wraps a {@link org.jboss.marshalling.MarshallerFactory}.
+ */
+public final class BasicMarshallingProtocol implements MarshallingProtocol {
+
+    private final MarshallerFactory marshallerFactory;
+    private final int version;
+
+    private static final SunReflectiveCreator creator = AccessController.doPrivileged(new PrivilegedAction<SunReflectiveCreator>() {
+        public SunReflectiveCreator run() {
+            return new SunReflectiveCreator();
+        }
+    });
+
+    /**
+     * Construct a new instance.
+     *
+     * @param marshallerFactory the marshaller factory to use
+     * @param version the wire protocol version to specify
+     */
+    public BasicMarshallingProtocol(final MarshallerFactory marshallerFactory, final int version) {
+        // todo: security check?
+        this.marshallerFactory = marshallerFactory;
+        this.version = version;
+    }
+
+    /** {@inheritDoc} */
+    public Pool<Unmarshaller> getUnmarshallerPool(final Configuration configuration) {
+        final MarshallingConfiguration config = buildConfig(configuration);
+        return new Pool<Unmarshaller>() {
+            public Unmarshaller allocate() {
+                try {
+                    return marshallerFactory.createUnmarshaller(config);
+                } catch (IOException e) {
+                    // todo log
+                    return null;
+                }
+            }
+
+            public void free(final Unmarshaller resource) throws IllegalArgumentException {
+            }
+
+            public void discard(final Unmarshaller resource) {
+            }
+        };
+    }
+
+    /** {@inheritDoc} */
+    public Pool<Marshaller> getMarshallerPool(final Configuration configuration) {
+        final MarshallingConfiguration config = buildConfig(configuration);
+        return new Pool<Marshaller>() {
+            public Marshaller allocate() {
+                try {
+                    return marshallerFactory.createMarshaller(config);
+                } catch (IOException e) {
+                    // todo log
+                    return null;
+                }
+            }
+
+            public void free(final Marshaller resource) throws IllegalArgumentException {
+            }
+
+            public void discard(final Marshaller resource) {
+            }
+        };
+    }
+
+    private MarshallingConfiguration buildConfig(final Configuration configuration) {
+        final MarshallingConfiguration config = new MarshallingConfiguration();
+        config.setCreator(creator);
+        config.setStreamHeader(Marshalling.nullStreamHeader());
+        config.setClassExternalizerFactory(configuration.getUserExternalizerFactory());
+        config.setClassTable(configuration.getUserClassTable());
+        config.setClassResolver(configuration.getUserClassResolver());
+        config.setObjectResolver(configuration.getUserObjectResolver());
+        config.setObjectTable(configuration.getUserObjectTable());
+        final OptionMap optionMap = configuration.getOptionMap();
+        config.setBufferSize(optionMap.get(Options.BUFFER_SIZE, 512));
+        config.setClassCount(optionMap.get(Options.CLASS_COUNT, 64));
+        config.setInstanceCount(optionMap.get(Options.INSTANCE_COUNT, 256));
+        config.setVersion(version);
+        return config;
+    }
+}

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CopyOnWriteHashMap.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CopyOnWriteHashMap.java	2009-10-23 21:19:18 UTC (rev 5568)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CopyOnWriteHashMap.java	2009-10-23 22:24:45 UTC (rev 5569)
@@ -26,6 +26,7 @@
 import java.util.Set;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.IdentityHashMap;
 import static java.util.Collections.emptyMap;
 import static java.util.Collections.singletonMap;
 import static java.util.Collections.unmodifiableMap;
@@ -34,6 +35,7 @@
 import java.util.concurrent.ConcurrentMap;
 
 final class CopyOnWriteHashMap<K, V> implements ConcurrentMap<K, V> {
+    private final boolean identity;
     private final Object writeLock;
     private volatile Map<K, V> map = emptyMap();
 
@@ -42,6 +44,11 @@
     }
 
     CopyOnWriteHashMap(final Object writeLock) {
+        this(false, writeLock);
+    }
+
+    CopyOnWriteHashMap(final boolean identity, final Object writeLock) {
+        this.identity = identity;
         this.writeLock = writeLock;
     }
 
@@ -59,7 +66,7 @@
             if (map.size() == 0) {
                 this.map = singletonMap(key, value);
             } else {
-                final HashMap<K, V> copy = new HashMap<K, V>(map);
+                final Map<K, V> copy = copy(map);
                 map.put(key, value);
                 this.map = copy;
             }
@@ -78,7 +85,7 @@
             if (map.size() == 1) {
                 this.map = emptyMap();
             } else {
-                final HashMap<K, V> copy = new HashMap<K, V>(map);
+                final Map<K, V> copy = copy(map);
                 map.remove(key);
                 this.map = copy;
             }
@@ -100,7 +107,7 @@
             if (map.size() == 1) {
                 this.map = singletonMap(key, newValue);
             } else {
-                final HashMap<K, V> copy = new HashMap<K, V>(map);
+                final Map<K, V> copy = copy(map);
                 map.put(key, newValue);
                 this.map = copy;
             }
@@ -122,7 +129,7 @@
                 if (map.size() == 1) {
                     this.map = singletonMap(key, value);
                 } else {
-                    final HashMap<K, V> copy = new HashMap<K, V>(map);
+                    final Map<K, V> copy = copy(map);
                     map.put(key, value);
                     this.map = copy;
                 }
@@ -164,7 +171,7 @@
             if (map.size() == 0) {
                 this.map = singletonMap(key, value);
             } else {
-                final HashMap<K, V> copy = new HashMap<K, V>(map);
+                final Map<K, V> copy = copy(map);
                 map.put(key, value);
                 this.map = copy;
             }
@@ -181,7 +188,7 @@
                 if (map.size() == 1) {
                     this.map = emptyMap();
                 } else {
-                    final HashMap<K, V> copy = new HashMap<K, V>(map);
+                    final Map<K, V> copy = copy(map);
                     map.remove(key);
                     this.map = copy;
                 }
@@ -190,6 +197,10 @@
         }
     }
 
+    private Map<K, V> copy(final Map<K, V> map) {
+        return identity ? new IdentityHashMap<K,V>(map) : new HashMap<K, V>(map);
+    }
+
     public void putAll(final Map<? extends K, ? extends V> m) {
     }
 

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java	2009-10-23 21:19:18 UTC (rev 5568)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java	2009-10-23 22:24:45 UTC (rev 5569)
@@ -83,6 +83,10 @@
         return new CopyOnWriteHashMap<K, V>(lock);
     }
 
+    static <K, V> ConcurrentMap<K, V> concurrentIdentityMap(Object lock) {
+        return new CopyOnWriteHashMap<K, V>(true, lock);
+    }
+
     static <T> Set<T> concurrentSet(Object lock) {
         return Collections.<T>newSetFromMap(EndpointImpl.<T, Boolean>concurrentMap(lock));
     }
@@ -113,7 +117,7 @@
      */
     private final Object serviceRegistrationLock = new Object();
 
-    private final Set<ListenerRegistration<ServiceRegistrationListener>> serviceListenerRegistrations = Collections.newSetFromMap(EndpointImpl.<ListenerRegistration<ServiceRegistrationListener>, Boolean>concurrentMap(serviceRegistrationLock));
+    private final ConcurrentMap<Registration, ServiceRegistrationListener> serviceListenerRegistrations = concurrentIdentityMap(serviceRegistrationLock);
     private final ConcurrentMap<String, ConcurrentMap<String, ServiceRegistration>> registeredLocalServices = concurrentMap(serviceRegistrationLock);
 
     private final ConcurrentMap<String, ConnectionProvider<?>> connectionProviders = concurrentMap();
@@ -244,7 +248,7 @@
             }
         };
         registration.setHandle(handle);
-        final Iterator<ListenerRegistration<ServiceRegistrationListener>> serviceListenerRegistrations;
+        final Iterator<Map.Entry<Registration,ServiceRegistrationListener>> serviceListenerRegistrations;
         final Object lock = serviceRegistrationLock;
         synchronized (lock) {
             // actually register the service, and while we have the lock, snag a copy of the registration listener list
@@ -260,7 +264,7 @@
             }
             submap.put(canonGroupName, registration);
             // snapshot
-            serviceListenerRegistrations = this.serviceListenerRegistrations.iterator();
+            serviceListenerRegistrations = this.serviceListenerRegistrations.entrySet().iterator();
         }
         // notify all service listener registrations that were registered at the time the service was created
         final ServiceRegistrationListener.ServiceInfo serviceInfo = new ServiceRegistrationListener.ServiceInfo();
@@ -271,12 +275,11 @@
         serviceInfo.setRequestHandlerConnector(requestHandlerConnector);
         executor.execute(new Runnable() {
             public void run() {
-                final Iterator<ListenerRegistration<ServiceRegistrationListener>> iter = serviceListenerRegistrations;
+                final Iterator<Map.Entry<Registration,ServiceRegistrationListener>> iter = serviceListenerRegistrations;
                 while (iter.hasNext()) {
-                    final ListenerRegistration<ServiceRegistrationListener> slr = iter.next();
-                    final ServiceRegistrationListener registrationListener = slr.getResource();
+                    final Map.Entry<Registration,ServiceRegistrationListener> slr = iter.next();
                     try {
-                        registrationListener.serviceRegistered(slr, serviceInfo.clone());
+                        slr.getValue().serviceRegistered(slr.getKey(), serviceInfo.clone());
                     } catch (Throwable t) {
                         logListenerError(t);
                     }
@@ -329,9 +332,13 @@
             sm.checkPermission(ADD_SERVICE_LISTENER_PERM);
         }
         final List<ServiceRegistration> services;
-        final ListenerRegistration<ServiceRegistrationListener> registration = new ListenerRegistration<ServiceRegistrationListener>(listener);
+        final Registration registration = new Registration() {
+            public void close() {
+                serviceListenerRegistrations.remove(this);
+            }
+        };
         synchronized (serviceRegistrationLock) {
-            serviceListenerRegistrations.add(registration);
+            serviceListenerRegistrations.put(registration, listener);
             if (flags == null || ! flags.contains(ListenerFlag.INCLUDE_OLD)) {
                 // need to make a copy of the whole list
                 services = new ArrayList<ServiceRegistration>();
@@ -575,24 +582,6 @@
         }
     }
 
-    private final class ListenerRegistration<T> implements Registration {
-        private final T resource;
-
-        private ListenerRegistration(final T resource) {
-            this.resource = resource;
-        }
-
-        public void close() {
-            synchronized (serviceRegistrationLock) {
-                serviceListenerRegistrations.remove(this);
-            }
-        }
-
-        T getResource() {
-            return resource;
-        }
-    }
-
     private final ConnectionContext localConnectionContext = new LocalConnectionContext();
     private final ConnectionHandler loopbackConnectionHandler = new LoopbackConnectionHandler();
     private final Connection loopbackConnection = new LoopbackConnection();
@@ -604,7 +593,7 @@
         }
     }
 
-    final class LocalConnectionProvider implements ConnectionProvider<Void> {
+    private final class LocalConnectionProvider implements ConnectionProvider<Void> {
 
         public Cancellable connect(final URI uri, final OptionMap connectOptions, final Result<ConnectionHandlerFactory> result) throws IllegalArgumentException {
             result.setResult(new ConnectionHandlerFactory() {

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java	2009-10-23 21:19:18 UTC (rev 5568)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java	2009-10-23 22:24:45 UTC (rev 5569)
@@ -88,4 +88,19 @@
      * Specify that the registered service should or should not be visible remotely.  If not specified, defaults to {@code true}.
      */
     public static final Option<Boolean> REMOTELY_VISIBLE = Option.simple(Options.class, "REMOTELY_VISIBLE", Boolean.class);
+
+    /**
+     * Specify the buffer size for any configured marshaller or unmarshaller.
+     */
+    public static final Option<Integer> BUFFER_SIZE = Option.simple(Options.class, "BUFFER_SIZE", Integer.class);
+
+    /**
+     * Specify the expected class count for any configured marshaller or unmarshaller.
+     */
+    public static final Option<Integer> CLASS_COUNT = Option.simple(Options.class, "CLASS_COUNT", Integer.class);
+
+    /**
+     * Specify the expected instance count for any configured marshaller or unmarshaller.
+     */
+    public static final Option<Integer> INSTANCE_COUNT = Option.simple(Options.class, "INSTANCE_COUNT", Integer.class);
 }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/MarshallingProtocol.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/MarshallingProtocol.java	2009-10-23 21:19:18 UTC (rev 5568)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/MarshallingProtocol.java	2009-10-23 22:24:45 UTC (rev 5569)
@@ -30,6 +30,7 @@
 import org.jboss.marshalling.ClassResolver;
 import org.jboss.marshalling.ObjectResolver;
 import org.jboss.xnio.Pool;
+import org.jboss.xnio.OptionMap;
 
 /**
  * A registered marshalling protocol.
@@ -95,5 +96,12 @@
          * @return the user object resolver
          */
         ObjectResolver getUserObjectResolver();
+
+        /**
+         * Get the options to use for this marshaller configuration.
+         *
+         * @return the options
+         */
+        OptionMap getOptionMap();
     }
 }



More information about the jboss-remoting-commits mailing list