/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opendj3/legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opendj3/legal-notices/CDDLv1_0.txt. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * Copyright 2012 ForgeRock AS */ package com.forgerock.opendj.ldap; import java.io.IOException; import java.util.concurrent.TimeUnit; import org.glassfish.grizzly.*; import org.glassfish.grizzly.attributes.AttributeHolder; import org.glassfish.grizzly.monitoring.MonitoringConfig; /** * A Grizzly connection which synchronizes write requests in order to workaround * issue GRIZZLY-1191 (http://java.net/jira/browse/GRIZZLY-1191). See OPENDJ-422 * (https://bugster.forgerock.org/jira/browse/OPENDJ-422) for more information. *

* This class should be removed once we issue GRIZZLY-422 is resolved and/or we * move to non-blocking IO (requires Grizzly 2.2). */ final class SynchronizedConnection implements Connection { private final Connection connection; private final Object writeLock = new Object(); /** * Returns a synchronized view of the provided Grizzly connection. * * @param connection * The Grizzly connection to be synchronized. * @return The synchronized view of the provided Grizzly connection. */ static SynchronizedConnection synchronizeConnection( Connection connection) { if (connection instanceof SynchronizedConnection) { return (SynchronizedConnection) connection; } else { return new SynchronizedConnection(connection); } } private SynchronizedConnection(Connection connection) { this.connection = connection; } /** * Returns the underlying unsynchronized connection. * * @return The underlying unsynchronized connection. */ Connection getUnsynchronizedConnection() { return connection; } public GrizzlyFuture> write(M message) throws IOException { synchronized (writeLock) { return connection.write(message); } } public GrizzlyFuture> read() throws IOException { return connection.read(); } public AttributeHolder getAttributes() { return connection.getAttributes(); } public GrizzlyFuture> read( CompletionHandler> completionHandler) throws IOException { return connection.read(completionHandler); } public Transport getTransport() { return connection.getTransport(); } public GrizzlyFuture> write(M message, CompletionHandler> completionHandler) throws IOException { synchronized (writeLock) { return connection.write(message, completionHandler); } } public boolean isOpen() { return connection.isOpen(); } public void configureBlocking(boolean isBlocking) { connection.configureBlocking(isBlocking); } public GrizzlyFuture> write(L dstAddress, M message, CompletionHandler> completionHandler) throws IOException { synchronized (writeLock) { return connection.write(dstAddress, message, completionHandler); } } public boolean isBlocking() { return connection.isBlocking(); } public void configureStandalone(boolean isStandalone) { connection.configureStandalone(isStandalone); } public boolean isStandalone() { return connection.isStandalone(); } @SuppressWarnings("rawtypes") public Processor obtainProcessor(IOEvent ioEvent) { return connection.obtainProcessor(ioEvent); } @SuppressWarnings("rawtypes") public Processor getProcessor() { return connection.getProcessor(); } @SuppressWarnings("rawtypes") public void setProcessor(Processor preferableProcessor) { connection.setProcessor(preferableProcessor); } public ProcessorSelector getProcessorSelector() { return connection.getProcessorSelector(); } public void setProcessorSelector(ProcessorSelector preferableProcessorSelector) { connection.setProcessorSelector(preferableProcessorSelector); } public L getPeerAddress() { return connection.getPeerAddress(); } public L getLocalAddress() { return connection.getLocalAddress(); } @SuppressWarnings("rawtypes") public GrizzlyFuture close() throws IOException { synchronized (writeLock) { return connection.close(); } } @SuppressWarnings("rawtypes") public GrizzlyFuture close( CompletionHandler completionHandler) throws IOException { synchronized (writeLock) { return connection.close(completionHandler); } } public int getReadBufferSize() { return connection.getReadBufferSize(); } public void setReadBufferSize(int readBufferSize) { connection.setReadBufferSize(readBufferSize); } public int getWriteBufferSize() { return connection.getWriteBufferSize(); } public void setWriteBufferSize(int writeBufferSize) { connection.setWriteBufferSize(writeBufferSize); } public long getReadTimeout(TimeUnit timeUnit) { return connection.getReadTimeout(timeUnit); } public void setReadTimeout(long timeout, TimeUnit timeUnit) { connection.setReadTimeout(timeout, timeUnit); } public long getWriteTimeout(TimeUnit timeUnit) { return connection.getWriteTimeout(timeUnit); } public void setWriteTimeout(long timeout, TimeUnit timeUnit) { connection.setWriteTimeout(timeout, timeUnit); } public void enableIOEvent(IOEvent ioEvent) throws IOException { connection.enableIOEvent(ioEvent); } public void disableIOEvent(IOEvent ioEvent) throws IOException { connection.disableIOEvent(ioEvent); } public MonitoringConfig getMonitoringConfig() { return connection.getMonitoringConfig(); } public void addCloseListener( org.glassfish.grizzly.Connection.CloseListener closeListener) { connection.addCloseListener(closeListener); } public boolean removeCloseListener( org.glassfish.grizzly.Connection.CloseListener closeListener) { return connection.removeCloseListener(closeListener); } public void notifyConnectionError(Throwable error) { connection.notifyConnectionError(error); } public String toString() { return connection.toString(); } }