jdk.dio.BufferAccess Maven / Gradle / Ivy
Show all versions of org.openjdk.dio Show documentation
/*
* Copyright (c) 2013, 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package jdk.dio;
import java.io.*;
import java.nio.*;
/**
* The {@code BufferAccess} interface provides methods for getting access to the
* device (or the driver thereof) I/O buffers, if any. A device driver may through
* this interface provide access to direct buffers that are suitable for efficient
* direct I/O operations such as using Direct Memory Access (DMA). This interface
* additionally provides a method that wraps an application-provided direct buffer
* into a buffer suitable for efficient direct I/O operations.
*
* The following sample code illustrates how the internal device's buffer might be used
* to perform efficient I/O operations (assuming the feature is supported):
*
*
* // Iterativelly creates a series of samples according to some requirement...
* private boolean createSamples(IntBuffer buffer) { ... }
*
* // Generates the sampled output signal; this code is more efficient if all the
* // samples to generate fit within the device's output buffer.
* try (DACChannel dac = DeviceManager.open(channelID)) {
* IntBuffer buffer = dac.getOutputBuffer();
* while (createSamples(buffer)) { // Directly creates the samples in the driver's internal buffer
* dac.generate(buffer);
* buffer.clear();
* }
* } catch (IOException ex) {
* // ...
* }
*
*
*
* The following sample code illustrates how an application may use a (pre-allocated) direct buffer to
* to perform efficient I/O operations (assuming the feature is supported):
*
*
* ByteBuffer someBuffer = ... // Some already allocated buffer
* try (DACChannel dac = DeviceManager.open(channelID)) {
* someBuffer.clear(); // Clear the buffer to make sure its full capacity can be used
* IntBuffer buffer = dac.prepareBuffer(someBuffer, 128);
* if (buffer == null) { // The provided buffer is not direct and/or is not suitable for efficient transfer
* buffer = someBuffer.asIntBuffer(); // The device will default to less efficient transfer mode
* }
* while (createSamples(buffer)) {
* dac.generate(buffer);
* buffer.clear();
* }
* } catch (IOException ex) {
* // ...
* }
* }
*
*
*
* Buffers are not safe for use by multiple concurrent threads so care should be
* taken to not access the device I/O buffers until any on-going operation has
* completed. Interfering with an on-going I/O operation by accessing and
* modifying a device I/O buffer concurrently may yield unpredictable results.
*
*
* @param the I/O buffer type.
* @since 1.0
*/
@apimarker.API("device-io_1.1")
public interface BufferAccess {
/**
* Gets the direct input buffer of this device (optional
* operation).
*
* The input buffer will get allocated on a per-application basis to avoid
* conflicts; but only one such buffer will be allocated per application. The
* capacity of the buffer will be determined based on the property of the
* underlying device.
*
* When the returned {@code Buffer} instance is invalidated because the device
* is either closed or in exclusive use by some other application then an
* attempt to access the {@code Buffer} instance will not change the buffer's
* content and will cause a {@code ClosedDeviceException} or some other
* unspecified exception to be thrown either at the time of the access or at
* some later time.
*
*
* @return the direct input buffer of this device.
* @throws UnsupportedOperationException if this device (or driver thereof)
* does not have or does not allow direct access to its input buffer.
* @throws ClosedDeviceException if the device has been closed.
* @throws IOException if an I/O error occurred such as the device is not
* readable.
*/
B getInputBuffer() throws ClosedDeviceException, IOException;
/**
* Gets the direct output buffer of this device (optional
* operation).
*
* The output buffer will get allocated on a per-application basis to avoid
* conflicts; but only one such buffer will be allocated per application. The
* capacity of the buffer will be determined based on the property of the
* underlying device.
*
* When the returned {@code Buffer} instance is invalidated because the device
* is either closed or in exclusive use by some other application then an
* attempt to access the {@code Buffer} instance will not change the buffer's
* content and will cause a {@code ClosedDeviceException} or some other
* unspecified exception to be thrown either at the time of the access or at
* some later time.
*
*
* @return the direct output buffer of this device.
* @throws UnsupportedOperationException if this device (or driver thereof)
* does not have or does not allow direct access to its output buffer.
* @throws ClosedDeviceException if the device has been closed.
* @throws IOException if an I/O error occurred such as the device is not
* writable.
*/
B getOutputBuffer() throws ClosedDeviceException, IOException;
/**
* Creates a view of the provided {@code ByteBuffer} suitable for efficient
* direct I/O transfers of the specified size and of the type required by this
* device. If the provided buffer is a direct buffer then the alignment of its current
* position, and its limit are checked; if eligible for direct I/O operation, a
* new buffer - of the required type - whose content is a shared subsequence of the provided
* buffer's content is created as follows:
*
* -
* The content of the new buffer will start at the provided buffer's current
* position - adjusted (incremented) for alignment, if necessary.
*
* -
* The new buffer's position will be zero, its capacity and its limit will be
* be set to the most optimal value lesser or equal to the requested size that
* can fit in the number of bytes remaining in the provided buffer - after
* adjustment for alignment; its mark will be undefined.
*
*
* Changes to the provided buffer's content will be visible in the new buffer,
* and vice versa; the two buffers' position, limit, and mark values will be
* independent.
* This device's driver will make a best effort to perform native (e.g. DMA)
* I/O operations directly upon the new buffer. If the remaining elements in
* the new buffer is less than the requested size then the application will
* have to submit the whole I/O operation in several rounds. If the new buffer
* is not at its full capacity when submitted for transfer - such as upon the very
* last round - then this device's driver may not be able to use efficient
* transfer and may resort to a less efficient mode of transfer.
*
* If the provided buffer is not direct or is not eligible for direct I/O (or
* if direct I/O is not supported) then {@code null} is returned. The
* provided buffer may still be used for the intended I/O operation but in
* this case, the device's driver may resort to less efficient procedures
* to perform the I/O operation.
*
*
* @param buffer the buffer to prepare for efficient I/O transfer.
* @param size the size of the intended data to transfer.
* @return a new buffer suitable for efficient I/O operations mapped onto the
* provided buffer, if one can be created; {@code null} otherwise.
* @throws IllegalArgumentException if {@code size} is negative.
* @throws ClosedDeviceException if the device has been closed.
* @throws IOException if some other I/O error occurs.
*
* @since 1.1
*/
B prepareBuffer(ByteBuffer buffer, int size) throws IOException, ClosedDeviceException;
}