You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by mh...@apache.org on 2006/11/24 21:20:29 UTC
svn commit: r478981 - in /mina/sandbox/mheath/aioj/trunk: ./ src/ src/main/
src/main/c/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/aio/ src/main/java/org/apache/aio/common/
src/main/java/org/apache/aio/posix/ s...
Author: mheath
Date: Fri Nov 24 12:20:28 2006
New Revision: 478981
URL: http://svn.apache.org/viewvc?view=rev&rev=478981
Log:
Moved from Directory sandbox to Mina sandbox.
Added:
mina/sandbox/mheath/aioj/trunk/LICENSE.txt
mina/sandbox/mheath/aioj/trunk/NOTICE.txt
mina/sandbox/mheath/aioj/trunk/pom.xml
mina/sandbox/mheath/aioj/trunk/src/
mina/sandbox/mheath/aioj/trunk/src/main/
mina/sandbox/mheath/aioj/trunk/src/main/c/
mina/sandbox/mheath/aioj/trunk/src/main/c/Makefile (with props)
mina/sandbox/mheath/aioj/trunk/src/main/c/org_apache_aio.cpp
mina/sandbox/mheath/aioj/trunk/src/main/java/
mina/sandbox/mheath/aioj/trunk/src/main/java/org/
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFuture.java
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureBatch.java
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureListener.java
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureReadWrite.java
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannel.java
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/BatchRequest.java
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Operation.java
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/common/
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/common/AbstractAioFuture.java
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/posix/
mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/posix/PosixAioFutureReadWrite.java
mina/sandbox/mheath/aioj/trunk/src/test/
mina/sandbox/mheath/aioj/trunk/src/test/java/
mina/sandbox/mheath/aioj/trunk/src/test/java/AIOTest.java
mina/sandbox/mheath/aioj/trunk/target/
mina/sandbox/mheath/aioj/trunk/target/jni/
mina/sandbox/mheath/aioj/trunk/target/test-classes/
mina/sandbox/mheath/aioj/trunk/todo.txt
Added: mina/sandbox/mheath/aioj/trunk/LICENSE.txt
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/LICENSE.txt?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/LICENSE.txt (added)
+++ mina/sandbox/mheath/aioj/trunk/LICENSE.txt Fri Nov 24 12:20:28 2006
@@ -0,0 +1,20 @@
+/*
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2006 Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
Added: mina/sandbox/mheath/aioj/trunk/NOTICE.txt
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/NOTICE.txt?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/NOTICE.txt (added)
+++ mina/sandbox/mheath/aioj/trunk/NOTICE.txt Fri Nov 24 12:20:28 2006
@@ -0,0 +1,2 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
Added: mina/sandbox/mheath/aioj/trunk/pom.xml
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/pom.xml?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/pom.xml (added)
+++ mina/sandbox/mheath/aioj/trunk/pom.xml Fri Nov 24 12:20:28 2006
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.aio</groupId>
+ <artifactId>aio</artifactId>
+ <version>0.1-SNAPSHOT</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <!-- this execution happens just after compiling the java classes, and builds the native code. -->
+ <id>build-native</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ <configuration>
+ <executable>src/main/c/Makefile</executable>
+ <workingDirectory>src/main/c</workingDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ </dependency>
+ </dependencies>
+
+</project>
Added: mina/sandbox/mheath/aioj/trunk/src/main/c/Makefile
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/c/Makefile?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/src/main/c/Makefile (added)
+++ mina/sandbox/mheath/aioj/trunk/src/main/c/Makefile Fri Nov 24 12:20:28 2006
@@ -0,0 +1,33 @@
+#!/usr/bin/make -f
+#
+# Makefile for C code
+#
+
+# C sources to compile
+
+TARGET_DIR := ../../../target
+TARGET := $(TARGET_DIR)/libaioj.so
+
+WORKING_DIR := $(TARGET_DIR)/jni
+
+JAVA_BUILD_DIR := $(TARGET_DIR)/classes
+
+JAVA_HOME ?= /opt/java/jdk
+
+INCLUDES := -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/linux -I $(WORKING_DIR)
+
+# classpath for javah
+ifdef CLASSPATH
+JAVAH_CLASSPATH = $(JAVA_BUILD_DIR):$(CLASSPATH)
+else
+JAVAH_CLASSPATH = $(JAVA_BUILD_DIR)
+endif
+
+all: $(TARGET)
+
+$(TARGET): org_apache_aio.cpp $(WORKING_DIR)/org_apache_aio_AsynchronousFileChannel.h $(WORKING_DIR)/org_apache_aio_posix_PosixAioFutureReadWrite.h
+ g++ -shared -lrt -lstdc++ $(INCLUDES) org_apache_aio.cpp -o $(TARGET)
+
+$(WORKING_DIR)/org_apache_aio_AsynchronousFileChannel.h $(WORKING_DIR)/org_apache_aio_posix_PosixAioFutureReadWrite.h: $(TARGET_DIR)/classes/org/apache/aio/AsynchronousFileChannel.class $(TARGET_DIR)/classes/org/apache/aio/posix/PosixAioFutureReadWrite.class
+ mkdir -p $(TARGET_DIR)/jni
+ javah -classpath $(JAVAH_CLASSPATH) -d $(WORKING_DIR) org.apache.aio.AsynchronousFileChannel org.apache.aio.posix.PosixAioFutureReadWrite
\ No newline at end of file
Propchange: mina/sandbox/mheath/aioj/trunk/src/main/c/Makefile
------------------------------------------------------------------------------
svn:executable = *
Added: mina/sandbox/mheath/aioj/trunk/src/main/c/org_apache_aio.cpp
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/c/org_apache_aio.cpp?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/src/main/c/org_apache_aio.cpp (added)
+++ mina/sandbox/mheath/aioj/trunk/src/main/c/org_apache_aio.cpp Fri Nov 24 12:20:28 2006
@@ -0,0 +1,369 @@
+#include <aio.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "org_apache_aio_AsynchronousFileChannel.h"
+#include "org_apache_aio_posix_PosixAioFutureReadWrite.h"
+
+#define DEBUG 1
+
+static JavaVM *jvm;
+static jclass ioException;
+static jclass nullPointerException;
+
+// --- Classes and IDs for PosixAioFutureReadWrite ---
+static jclass posixAioFutureReadWrite;
+static jmethodID CID_posixAioFutureReadWrite;
+static jmethodID posixAioFutureReadWrite_processFutureListenersID;
+static jfieldID posixAioFutureReadWrite_aiocbPtrID;
+static jfieldID posixAioFutureReadWrite_bufferID;
+
+static jfieldID fdID; // ID for java.io.FileDescriptor.fd
+static jfieldID fieldDescID; // ID for org.apache.aio.AsynchronousFileChannel.fd
+
+static jobject operationRead;
+static jobject operationWrite;
+static jobject operationBatchRead;
+static jobject operationBatchWrite;
+
+extern "C"
+{
+ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved);
+ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved);
+ void aio_read_completion_handler(sigval_t sigval);
+ void aio_write_completion_handler(sigval_t sigval);
+}
+
+// --- Utility Functions ----------------------------------------------------
+jint getFD(JNIEnv *env, jobject asynchFileChannel)
+{
+ jobject fieldDesc = env->GetObjectField(asynchFileChannel, fieldDescID);
+ return env->GetIntField(fieldDesc, fdID);
+}
+
+inline jint getBufferPosition(JNIEnv *env, jobject buffer)
+{
+ jclass cls = env->GetObjectClass(buffer);
+ jmethodID MID_position = env->GetMethodID(cls, "position", "()I");
+ return env->CallIntMethod(buffer, MID_position);
+}
+
+inline void setBufferPosition(JNIEnv *env, jobject buffer, jint position)
+{
+ jclass cls = env->GetObjectClass(buffer);
+ jmethodID MID_position = env->GetMethodID(cls, "position", "(I)Ljava/nio/Buffer;");
+ env->CallVoidMethod(buffer, MID_position, position);
+}
+
+inline jint getBufferLimit(JNIEnv *env, jobject buffer)
+{
+ jclass cls = env->GetObjectClass(buffer);
+ jmethodID MID_limit = env->GetMethodID(cls, "limit", "()I");
+ return env->CallIntMethod(buffer, MID_limit);
+}
+
+inline void setBufferLimit(JNIEnv *env, jobject buffer, jint limit)
+{
+ jclass cls = env->GetObjectClass(buffer);
+ jmethodID MID_limit = env->GetMethodID(cls, "limit", "(I)Ljava/nio/Buffer;");
+ env->CallVoidMethod(buffer, MID_limit, limit);
+}
+
+jobject createPosixAioFutureReadWrite(JNIEnv *env, jobject channel, jobject operation, void *aiocb, jobject buffer, long position)
+{
+ jvalue values[5];
+ values[0].l = channel;
+ values[1].l = operation;
+ values[2].j = (jlong)aiocb;
+ values[3].l = buffer;
+ values[4].j = position;
+ jobject future = env->NewObjectA(posixAioFutureReadWrite, CID_posixAioFutureReadWrite, values);
+ return env->NewGlobalRef(future);
+}
+
+struct aiocb *setupAioRequest(JNIEnv *env, jobject asynchronousFileChannel, jobject buffer, jlong position, jobject operation)
+{
+ // Get address and capacity of buffer
+ if (buffer == NULL)
+ {
+ env->ThrowNew(nullPointerException, "buffer cannot be null");
+ }
+ // TODO: Add support for non direct byte buffers
+ jbyte *bufferAddress = (jbyte *)env->GetDirectBufferAddress(buffer);
+ if (bufferAddress == NULL)
+ {
+ env->ThrowNew(ioException, "Must use direct ByteBuffer");
+ return NULL;
+ }
+ // Adjust bufferAddress by the position of the buffer
+ jint bufferPosition = getBufferPosition(env, buffer);
+ bufferAddress += bufferPosition;
+ jint bufferSize = getBufferLimit(env, buffer) - position;
+
+ // Allocate aiocb
+ struct aiocb *req = (aiocb*)malloc(sizeof(aiocb));
+ bzero(req, sizeof(struct aiocb));
+
+ jobject future = createPosixAioFutureReadWrite(env, asynchronousFileChannel, operation, req, buffer, position);
+
+ // Setup aiocb
+ req->aio_fildes = getFD(env, asynchronousFileChannel);
+ req->aio_offset = position;
+ req->aio_buf = bufferAddress;
+ req->aio_nbytes = bufferSize;
+
+ req->aio_sigevent.sigev_notify = SIGEV_THREAD;
+ if (operation == operationRead)
+ {
+ req->aio_sigevent.sigev_notify_function = aio_read_completion_handler;
+ } else if (operation == operationWrite) {
+ req->aio_sigevent.sigev_notify_function = aio_write_completion_handler;
+ }
+ req->aio_sigevent.sigev_notify_attributes = NULL;
+ req->aio_sigevent.sigev_value.sival_ptr = future;
+
+ return req;
+}
+
+// --- OnLoad and OnUnload Functions ----------------------------------------
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
+{
+ jint JNIversion = JNI_VERSION_1_4;
+ if (DEBUG)
+ {
+ fprintf(stdout, "Initializing native code for JNI version 0x%x\n", JNIversion);
+ fflush(stdout);
+ }
+
+ // Initialize static jvm pointer.
+ jvm = vm;
+
+ JNIEnv *env;
+ if (vm->GetEnv((void**)&env, JNIversion))
+ {
+ return JNI_ERR;
+ }
+
+ jclass cls;
+ cls = env->FindClass("java/io/IOException");
+ ioException = (jclass)env->NewWeakGlobalRef(cls);
+
+ cls = env->FindClass("java/lang/NullPointerException");
+ nullPointerException = (jclass)env->NewWeakGlobalRef(cls);
+
+ cls = env->FindClass("org/apache/aio/posix/PosixAioFutureReadWrite");
+ posixAioFutureReadWrite = (jclass)env->NewWeakGlobalRef(cls);
+ CID_posixAioFutureReadWrite = env->GetMethodID(posixAioFutureReadWrite, "<init>", "(Lorg/apache/aio/AsynchronousFileChannel;Lorg/apache/aio/Operation;JLjava/nio/ByteBuffer;J)V");
+ posixAioFutureReadWrite_processFutureListenersID = env->GetMethodID(posixAioFutureReadWrite, "processFutureListeners", "()V");
+ posixAioFutureReadWrite_aiocbPtrID = env->GetFieldID(posixAioFutureReadWrite, "aiocbPtr", "J");
+ posixAioFutureReadWrite_bufferID = env->GetFieldID(posixAioFutureReadWrite, "buffer", "Ljava/nio/ByteBuffer;");
+
+ cls = env->FindClass("java/io/FileDescriptor");
+ fdID = env->GetFieldID(cls, "fd", "I");
+
+ cls = env->FindClass("org/apache/aio/AsynchronousFileChannel");
+ fieldDescID = env->GetFieldID(cls, "fd", "Ljava/io/FileDescriptor;");
+
+ cls = env->FindClass("org/apache/aio/Operation");
+ jfieldID fid;
+ fid = env->GetStaticFieldID(cls, "READ", "Lorg/apache/aio/Operation;");
+ operationRead = env->NewWeakGlobalRef(env->GetStaticObjectField(cls, fid));
+ fid = env->GetStaticFieldID(cls, "WRITE", "Lorg/apache/aio/Operation;");
+ operationWrite = env->NewWeakGlobalRef(env->GetStaticObjectField(cls, fid));
+ fid = env->GetStaticFieldID(cls, "BATCH_READ", "Lorg/apache/aio/Operation;");
+ operationBatchRead = env->NewWeakGlobalRef(env->GetStaticObjectField(cls, fid));
+ fid = env->GetStaticFieldID(cls, "BATCH_WRITE", "Lorg/apache/aio/Operation;");
+ operationBatchWrite = env->NewWeakGlobalRef(env->GetStaticObjectField(cls, fid));
+
+ return JNIversion;
+}
+
+JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
+{
+ jint JNIversion = JNI_VERSION_1_4;
+ JNIEnv *env;
+ if (vm->GetEnv((void**)&env, JNIversion))
+ {
+ return;
+ }
+
+ env->DeleteWeakGlobalRef(ioException);
+ env->DeleteWeakGlobalRef(nullPointerException);
+ env->DeleteWeakGlobalRef(posixAioFutureReadWrite);
+ env->DeleteWeakGlobalRef(operationRead);
+ env->DeleteWeakGlobalRef(operationWrite);
+ env->DeleteWeakGlobalRef(operationBatchRead);
+ env->DeleteWeakGlobalRef(operationBatchWrite);
+}
+
+// --- AsynchronousFileChannel method implementations ----------------------
+JNIEXPORT jobject JNICALL Java_org_apache_aio_AsynchronousFileChannel_write
+ (JNIEnv *env, jobject obj, jobject buffer, jlong position)
+{
+ if (DEBUG)
+ {
+ fprintf(stdout, "aio write at file position %d\n", position);
+ fflush(stdout);
+ }
+ struct aiocb *req = setupAioRequest(env, obj, buffer, position, operationWrite);
+ int ret = aio_write(req);
+ if (ret)
+ {
+ // TODO Handle errors from ret
+ // return a null on error.
+ return NULL;
+ }
+ return (jobject)req->aio_sigevent.sigev_value.sival_ptr;
+}
+
+JNIEXPORT jobject JNICALL Java_org_apache_aio_AsynchronousFileChannel_read
+ (JNIEnv *env, jobject obj, jobject buffer, jlong position)
+{
+ if (DEBUG)
+ {
+ fprintf(stdout, "aio read at file position %d\n", position);
+ fflush(stdout);
+ }
+ struct aiocb *req = setupAioRequest(env, obj, buffer, position, operationRead);
+ if (DEBUG)
+ {
+ fprintf(stdout, "Do aio read\n");
+ fflush(stdout);
+ }
+ int ret = aio_read(req);
+ if (ret)
+ {
+ // TODO Handle errors from ret
+ // return a null on error.
+ return NULL;
+ }
+
+ // Return future object
+ return (jobject)req->aio_sigevent.sigev_value.sival_ptr;
+}
+
+JNIEXPORT jobject JNICALL Java_org_apache_aio_AsynchronousFileChannel_batchRead
+ (JNIEnv *env, jobject obj, jobjectArray batch)
+{
+ printf("batchRead\n");
+ return NULL;
+}
+
+JNIEXPORT jobject JNICALL Java_org_apache_aio_AsynchronousFileChannel_batchWrite
+ (JNIEnv *env, jobject obj, jobjectArray batch)
+{
+ printf("batchWrite\n");
+ return NULL;
+}
+
+JNIEXPORT void JNICALL Java_org_apache_aio_AsynchronousFileChannel_suspend
+ (JNIEnv *env, jobject obj, jobjectArray futures)
+{
+ printf("suspend\n");
+}
+
+// --- PosixAioFutureReadWrite methods ---------------------------------------------------
+JNIEXPORT jboolean JNICALL Java_org_apache_aio_posix_PosixAioFutureReadWrite_cancel
+ (JNIEnv *env, jobject obj)
+{
+ struct aiocb *req = (struct aiocb *)env->GetLongField(obj, posixAioFutureReadWrite_aiocbPtrID);
+ int ret = aio_cancel(req->aio_fildes, req);
+ if (ret == AIO_CANCELED)
+ {
+ free(req);
+ return 1;
+ }
+ return 0;
+}
+
+// --- Completion handlers ----------------------------------------------------------------
+void aio_read_completion_handler(sigval_t sigval)
+{
+ if (DEBUG)
+ {
+ fprintf(stdout, "In read completion handler\n");
+ fflush(stdout);
+ }
+
+ JNIEnv *env;
+ jint res = jvm->AttachCurrentThread((void**)&env, NULL);
+ if (res < 0)
+ {
+ fprintf(stderr, "Failed to attach JVM to AIO read thread\n");
+ return;
+ }
+
+ jobject future = (jobject)sigval.sival_ptr;
+ struct aiocb *req = (struct aiocb *)env->GetLongField(future, posixAioFutureReadWrite_aiocbPtrID);
+
+ /* Did the request complete? */
+ if (aio_error(req) == 0) {
+ /* Request completed successfully, get number of bytes processed */
+ int ret = aio_return( req );
+
+ // Adjust buffer limit
+ jobject buffer = env->GetObjectField(future, posixAioFutureReadWrite_bufferID);
+ int limit = ret + getBufferPosition(env, buffer);
+ setBufferLimit(env, buffer, limit);
+
+ // Call aio listeners
+ env->CallVoidMethod(future, posixAioFutureReadWrite_processFutureListenersID);
+
+ // Free resources
+ free(req);
+ env->DeleteGlobalRef(future);
+ } else {
+ // TODO Find a way to handle exception here
+ fprintf(stderr, "ERROR: AIO read request did NOT complete\n");
+ fflush(stderr);
+ }
+
+ jvm->DetachCurrentThread();
+ return;
+}
+
+void aio_write_completion_handler(sigval_t sigval)
+{
+ if (DEBUG)
+ {
+ fprintf(stdout, "In write completion handler\n");
+ fflush(stdout);
+ }
+
+ JNIEnv *env;
+ jint res = jvm->AttachCurrentThread((void**)&env, NULL);
+ if (res < 0)
+ {
+ fprintf(stderr, "Failed to attach JVM to AIO write thread\n");
+ return;
+ }
+
+ jobject future = (jobject)sigval.sival_ptr;
+ struct aiocb *req = (struct aiocb *)env->GetLongField(future, posixAioFutureReadWrite_aiocbPtrID);
+
+ /* Did the request complete? */
+ if (aio_error(req) == 0) {
+ /* Request completed successfully, get number of bytes processed */
+ int ret = aio_return( req );
+
+ // Adjust buffer position
+ jobject buffer = env->GetObjectField(future, posixAioFutureReadWrite_bufferID);
+ int position = getBufferPosition(env, buffer) + ret;
+ setBufferPosition(env, buffer, position);
+
+ // Call aio listeners
+ env->CallVoidMethod(future, posixAioFutureReadWrite_processFutureListenersID);
+
+ // Free resources
+ free(req);
+ env->DeleteGlobalRef(future);
+ } else {
+ // TODO Find a way to handle exception here
+ fprintf(stderr, "ERROR: AIO write request did NOT complete\n");
+ fflush(stderr);
+ }
+
+ jvm->DetachCurrentThread();
+ return;
+}
Added: mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFuture.java
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFuture.java?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFuture.java (added)
+++ mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFuture.java Fri Nov 24 12:20:28 2006
@@ -0,0 +1,23 @@
+package org.apache.aio;
+
+import java.util.concurrent.TimeUnit;
+
+public interface AioFuture<T extends AioFuture> {
+
+ public void addListener(AioFutureListener<T> ioFutureListener);
+
+ public void removeListener(AioFutureListener<T> ioFutureListener);
+
+ public AsynchronousFileChannel getChannel();
+
+ public boolean isCompleted();
+
+ public void join() throws InterruptedException;
+
+ public boolean join(long timeout, TimeUnit timeUnit) throws InterruptedException;
+
+ public boolean cancel();
+
+ public Operation getOperation();
+
+}
Added: mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureBatch.java
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureBatch.java?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureBatch.java (added)
+++ mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureBatch.java Fri Nov 24 12:20:28 2006
@@ -0,0 +1,10 @@
+package org.apache.aio;
+
+public interface AioFutureBatch extends AioFuture {
+
+ public void addListener(AioFutureListener<AioFutureBatch> ioFutureListener);
+
+ public void removeListener(AioFutureListener<AioFutureBatch> ioFutureListener);
+
+ public BatchRequest[] getRequests();
+}
Added: mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureListener.java
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureListener.java?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureListener.java (added)
+++ mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureListener.java Fri Nov 24 12:20:28 2006
@@ -0,0 +1,7 @@
+package org.apache.aio;
+
+public interface AioFutureListener<T extends AioFuture> {
+
+ public void onCompletion(T ioFuture);
+
+}
Added: mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureReadWrite.java
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureReadWrite.java?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureReadWrite.java (added)
+++ mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AioFutureReadWrite.java Fri Nov 24 12:20:28 2006
@@ -0,0 +1,11 @@
+package org.apache.aio;
+
+import java.nio.ByteBuffer;
+
+public interface AioFutureReadWrite extends AioFuture<AioFutureReadWrite> {
+
+ public ByteBuffer getBuffer();
+
+ public long getPosition();
+
+}
Added: mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannel.java
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannel.java?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannel.java (added)
+++ mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/AsynchronousFileChannel.java Fri Nov 24 12:20:28 2006
@@ -0,0 +1,44 @@
+package org.apache.aio;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class AsynchronousFileChannel {
+
+ static {
+ System.loadLibrary("aioj");
+ }
+
+ private FileDescriptor fd;
+
+ public AsynchronousFileChannel(FileDescriptor fd) throws IOException {
+ if (fd == null) {
+ throw new NullPointerException("fd cannot be null");
+ }
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkWrite(fd);
+ }
+ this.fd = fd;
+ }
+
+ public FileDescriptor getFD() {
+ return fd;
+ }
+
+ public boolean isOpen() {
+ return fd.valid();
+ }
+
+ public native AioFutureReadWrite write(ByteBuffer buffer, long position) throws IOException;
+
+ public native AioFutureReadWrite read(ByteBuffer buffer, long position) throws IOException;
+
+ public native AioFutureBatch batchRead(BatchRequest... reads) throws IOException;
+
+ public native AioFutureBatch batchWrite(BatchRequest... writes) throws IOException;
+
+ public native void suspend(AioFuture... futures) throws IOException;
+
+}
Added: mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/BatchRequest.java
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/BatchRequest.java?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/BatchRequest.java (added)
+++ mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/BatchRequest.java Fri Nov 24 12:20:28 2006
@@ -0,0 +1,23 @@
+package org.apache.aio;
+
+import java.nio.ByteBuffer;
+
+public class BatchRequest {
+
+ private final long position;
+ private final ByteBuffer buffer;
+
+ public BatchRequest(long position, ByteBuffer buffer) {
+ this.position = position;
+ this.buffer = buffer;
+ }
+
+ public ByteBuffer getBuffer() {
+ return buffer;
+ }
+
+ public long getPosition() {
+ return position;
+ }
+
+}
Added: mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Operation.java
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Operation.java?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Operation.java (added)
+++ mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/Operation.java Fri Nov 24 12:20:28 2006
@@ -0,0 +1,8 @@
+package org.apache.aio;
+
+public enum Operation {
+ READ,
+ WRITE,
+ BATCH_READ,
+ BATCH_WRITE
+}
Added: mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/common/AbstractAioFuture.java
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/common/AbstractAioFuture.java?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/common/AbstractAioFuture.java (added)
+++ mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/common/AbstractAioFuture.java Fri Nov 24 12:20:28 2006
@@ -0,0 +1,71 @@
+package org.apache.aio.common;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.aio.AioFuture;
+import org.apache.aio.AioFutureListener;
+import org.apache.aio.AsynchronousFileChannel;
+import org.apache.aio.Operation;
+
+public abstract class AbstractAioFuture<T extends AioFuture> implements AioFuture<T> {
+
+ private final AsynchronousFileChannel channel;
+ private final Operation operation;
+ private final List<AioFutureListener<T>> listeners = new LinkedList<AioFutureListener<T>>();
+ private volatile boolean completed = false;
+
+ protected AbstractAioFuture(AsynchronousFileChannel channel, Operation operation) {
+ this.channel = channel;
+ this.operation = operation;
+ }
+
+ @SuppressWarnings("unchecked")
+ public synchronized void addListener(AioFutureListener<T> ioFutureListener) {
+ if (completed) {
+ ioFutureListener.onCompletion((T)this);
+ } else {
+ listeners.add(ioFutureListener);
+ }
+ }
+
+ public AsynchronousFileChannel getChannel() {
+ return channel;
+ }
+
+ public Operation getOperation() {
+ return operation;
+ }
+
+ public boolean isCompleted() {
+ return completed;
+ }
+
+ public synchronized void join() throws InterruptedException {
+ if (!completed) {
+ wait();
+ }
+ }
+
+ public synchronized boolean join(long timeout, TimeUnit timeUnit) throws InterruptedException {
+ if (!completed) {
+ wait(timeUnit.toMillis(timeout));
+ }
+ return isCompleted();
+ }
+
+ public synchronized void removeListener(AioFutureListener<T> ioFutureListener) {
+ listeners.remove(ioFutureListener);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected synchronized void processFutureListeners() {
+ completed = true;
+ notifyAll();
+ for (AioFutureListener<T> listener : listeners) {
+ listener.onCompletion((T)this);
+ }
+ }
+
+}
Added: mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/posix/PosixAioFutureReadWrite.java
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/posix/PosixAioFutureReadWrite.java?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/posix/PosixAioFutureReadWrite.java (added)
+++ mina/sandbox/mheath/aioj/trunk/src/main/java/org/apache/aio/posix/PosixAioFutureReadWrite.java Fri Nov 24 12:20:28 2006
@@ -0,0 +1,35 @@
+package org.apache.aio.posix;
+
+import java.nio.ByteBuffer;
+
+import org.apache.aio.AioFutureReadWrite;
+import org.apache.aio.AsynchronousFileChannel;
+import org.apache.aio.Operation;
+import org.apache.aio.common.AbstractAioFuture;
+
+public class PosixAioFutureReadWrite extends AbstractAioFuture<AioFutureReadWrite> implements AioFutureReadWrite {
+
+ @SuppressWarnings("unused")
+ private final long aiocbPtr; // Used by native code
+
+ private final ByteBuffer buffer;
+ private final long position;
+
+ protected PosixAioFutureReadWrite(AsynchronousFileChannel channel, Operation operation, long aiocbPtr, ByteBuffer buffer, long position) {
+ super(channel, operation);
+ this.aiocbPtr = aiocbPtr;
+ this.buffer = buffer;
+ this.position = position;
+ }
+
+ public ByteBuffer getBuffer() {
+ return buffer;
+ }
+
+ public long getPosition() {
+ return position;
+ }
+
+ public native boolean cancel();
+
+}
Added: mina/sandbox/mheath/aioj/trunk/src/test/java/AIOTest.java
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/src/test/java/AIOTest.java?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/src/test/java/AIOTest.java (added)
+++ mina/sandbox/mheath/aioj/trunk/src/test/java/AIOTest.java Fri Nov 24 12:20:28 2006
@@ -0,0 +1,38 @@
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.nio.ByteBuffer;
+
+import org.apache.aio.AioFutureListener;
+import org.apache.aio.AioFutureReadWrite;
+import org.apache.aio.AsynchronousFileChannel;
+
+public class AIOTest {
+
+ public static void main(String[] args) throws Exception {
+ FileInputStream in = new FileInputStream("/etc/passwd");
+
+ AsynchronousFileChannel achannel = new AsynchronousFileChannel(in.getFD());
+
+ AioFutureListener<AioFutureReadWrite> listener = new AioFutureListener<AioFutureReadWrite>() {
+ public void onCompletion(AioFutureReadWrite ioFuture) {
+ System.out.println("In callback");
+ byte[] data = new byte[ioFuture.getBuffer().limit() - ioFuture.getBuffer().position()];
+ ioFuture.getBuffer().get(data);
+ System.out.println(" Buffer contains: " + new String(data));
+ }
+ };
+ ByteBuffer buffer = ByteBuffer.allocateDirect(4096);
+ AioFutureReadWrite future = achannel.read(buffer, 0);
+ future.addListener(listener);
+ future.join();
+
+ FileOutputStream out = new FileOutputStream("/tmp/foo");
+ achannel = new AsynchronousFileChannel(out.getFD());
+ buffer.clear();
+ buffer.put("Have a really nice day!\n".getBytes());
+ buffer.flip();
+ future = achannel.write(buffer, 0);
+ System.out.println(future);
+ }
+
+}
Added: mina/sandbox/mheath/aioj/trunk/todo.txt
URL: http://svn.apache.org/viewvc/mina/sandbox/mheath/aioj/trunk/todo.txt?view=auto&rev=478981
==============================================================================
--- mina/sandbox/mheath/aioj/trunk/todo.txt (added)
+++ mina/sandbox/mheath/aioj/trunk/todo.txt Fri Nov 24 12:20:28 2006
@@ -0,0 +1,7 @@
+- Add support for heap buffers
+- Throw IO Exceptions when aio calls return an error
+- Figure out batch requests
+
+=== Testing ===
+- Make sure the AsynchronousFileChannel can be unloaded without holding onto native references
+- Test for memory leaks
\ No newline at end of file