[561551] Eliminate Channel.receiveSerializer

https://bugs.eclipse.org/bugs/show_bug.cgi?id=561551
diff --git a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/apps/Profiling.java b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/apps/Profiling.java
new file mode 100644
index 0000000..4fda76d
--- /dev/null
+++ b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/apps/Profiling.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2008, 2009, 2011, 2012, 2015, 2016, 2019 Eike Stepper (Loehne, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Eike Stepper - initial API and implementation
+ *    Teerawat Chaiyakijpichet (No Magic Asia Ltd.) - SSL
+ */
+package org.eclipse.net4j.tests.apps;
+
+import org.eclipse.net4j.Net4jUtil;
+import org.eclipse.net4j.tcp.ITCPConnector;
+import org.eclipse.net4j.tcp.TCPUtil;
+import org.eclipse.net4j.tests.config.AbstractConfigTest;
+import org.eclipse.net4j.tests.data.HugeData;
+import org.eclipse.net4j.tests.signal.ArrayRequest;
+import org.eclipse.net4j.tests.signal.TestSignalProtocol;
+import org.eclipse.net4j.util.container.ContainerUtil;
+import org.eclipse.net4j.util.container.IManagedContainer;
+
+/**
+ * @author Eike Stepper
+ */
+public class Profiling extends AbstractConfigTest
+{
+  public static void main(String[] args) throws Exception
+  {
+    IManagedContainer container = ContainerUtil.createContainer();
+    ContainerUtil.prepareContainer(container);
+    Net4jUtil.prepareContainer(container);
+    TCPUtil.prepareContainer(container);
+    container.registerFactory(new TestSignalProtocol.Factory());
+    container.activate();
+
+    TCPUtil.getAcceptor(container, "0.0.0.0:2036");
+
+    ITCPConnector connector = TCPUtil.getConnector(container, "127.0.0.1:2036");
+    TestSignalProtocol protocol = new TestSignalProtocol(connector);
+
+    byte[] data = HugeData.getBytes();
+    for (int i = 0; i < 10000; i++)
+    {
+      new ArrayRequest(protocol, data).send();
+    }
+  }
+}
diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/channel/IChannel.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/channel/IChannel.java
index 2fb8a8f..93d9e10 100644
--- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/channel/IChannel.java
+++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/channel/IChannel.java
@@ -103,4 +103,19 @@
    * Sets the <code>IBufferHandler</code> to handle buffers received from the peer channel.
    */
   public void setReceiveHandler(IBufferHandler receiveHandler);
+
+  /**
+   * Returns the number of {@link IBuffer buffers} that are sent to the {@link IChannelMultiplexer multiplexer} of this channel.
+   *
+   * @since 4.10
+   */
+  public long getSentBuffers();
+
+  /**
+   * Returns the number of {@link IBuffer buffers} that are received from the {@link IChannelMultiplexer multiplexer} of this channel
+   * <b>and</b> are passed on to the {@link #getReceiveHandler() receive handler} of this channel.
+   *
+   * @since 4.10
+   */
+  public long getReceivedBuffers();
 }
diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/spi/net4j/Channel.java b/plugins/org.eclipse.net4j/src/org/eclipse/spi/net4j/Channel.java
index 22fa8f1..38b8d50 100644
--- a/plugins/org.eclipse.net4j/src/org/eclipse/spi/net4j/Channel.java
+++ b/plugins/org.eclipse.net4j/src/org/eclipse/spi/net4j/Channel.java
@@ -20,7 +20,6 @@
 import org.eclipse.net4j.util.concurrent.ConcurrencyUtil;
 import org.eclipse.net4j.util.concurrent.IExecutorServiceProvider;
 import org.eclipse.net4j.util.concurrent.RunnableWithName;
-import org.eclipse.net4j.util.concurrent.SerializingExecutor;
 import org.eclipse.net4j.util.event.Event;
 import org.eclipse.net4j.util.event.IListener;
 import org.eclipse.net4j.util.lifecycle.Lifecycle;
@@ -36,7 +35,6 @@
 import java.text.MessageFormat;
 import java.util.Queue;
 import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.Executor;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -56,8 +54,6 @@
 
   private short id = IBuffer.NO_CHANNEL;
 
-  private final Executor receiveSerializer = new SerializingExecutor();
-
   /**
    * The external handler for buffers passed from the {@link #connector}.
    */
@@ -280,20 +276,26 @@
       }
 
       ++receivedBuffers;
-
-      ReceiverWork receiverWork = createReceiverWork(buffer);
-      receiveSerializer.execute(receiverWork);
+      receiveHandler.handleBuffer(buffer);
     }
     else
     {
-      // Shutting down
+      if (TRACER.isEnabled())
+      {
+        TRACER.format("Releasing buffer from multiplexer for lack of receive handler: {0} --> {1}", buffer, this); //$NON-NLS-1$
+      }
+
       buffer.release();
     }
   }
 
+  /**
+   * @deprecated As of 4.10 scheduled for future removal.
+   */
+  @Deprecated
   protected ReceiverWork createReceiverWork(IBuffer buffer)
   {
-    return new ReceiverWork(buffer);
+    throw new UnsupportedOperationException();
   }
 
   @Override
@@ -343,15 +345,12 @@
     {
       sendQueue = new SendQueue();
     }
-
-    LifecycleUtil.activate(receiveSerializer);
   }
 
   @Override
   protected void doDeactivate() throws Exception
   {
     unregisterFromMultiplexer();
-    LifecycleUtil.deactivate(receiveSerializer);
 
     if (sendQueue != null)
     {
@@ -407,7 +406,9 @@
    * If the meaning of this type isn't clear, there really should be more of a description here...
    *
    * @author Eike Stepper
+   * @deprecated As of 4.10 scheduled for future removal.
    */
+  @Deprecated
   protected class ReceiverWork extends RunnableWithName
   {
     private final IBuffer buffer;
diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/spi/net4j/InternalChannel.java b/plugins/org.eclipse.net4j/src/org/eclipse/spi/net4j/InternalChannel.java
index 6bda1ad..965a12d 100644
--- a/plugins/org.eclipse.net4j/src/org/eclipse/spi/net4j/InternalChannel.java
+++ b/plugins/org.eclipse.net4j/src/org/eclipse/spi/net4j/InternalChannel.java
@@ -56,16 +56,6 @@
 
   public void handleBufferFromMultiplexer(IBuffer buffer);
 
-  /**
-   * @since 3.0
-   */
-  public long getReceivedBuffers();
-
-  /**
-   * @since 3.0
-   */
-  public long getSentBuffers();
-
   public Queue<IBuffer> getSendQueue();
 
   /**