From dddd1b4509cec1f4c25e6189f10186562f115fac Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Fri, 28 Mar 2014 16:50:26 +0100 Subject: implement direct buffers --- flow/src/main/native/posix/flow.c | 7 +++--- flow/src/main/native/posix/flow_jni.c | 29 ++++++++++++++++++++-- .../com/github/jodersky/flow/SerialManager.scala | 10 ++++++-- .../com/github/jodersky/flow/SerialOperator.scala | 4 +++ 4 files changed, 43 insertions(+), 7 deletions(-) (limited to 'flow/src') diff --git a/flow/src/main/native/posix/flow.c b/flow/src/main/native/posix/flow.c index c408670..7f7d54b 100644 --- a/flow/src/main/native/posix/flow.c +++ b/flow/src/main/native/posix/flow.c @@ -38,9 +38,10 @@ int serial_open( int fd = open(port_name, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd < 0) { + int en = errno; DEBUG(perror("error obtaining port file descriptor");); - if (errno == EACCES) return E_ACCESS_DENIED; - if (errno == ENOENT) return E_NO_PORT; + if (en == EACCES) return E_ACCESS_DENIED; + if (en == ENOENT) return E_NO_PORT; return E_IO; } @@ -214,7 +215,7 @@ int serial_read(struct serial_config* const serial, char* const buffer, size_t s //treat 0 bytes read as an error to avoid problems on disconnect //anyway, after a poll there should be more than 0 bytes available to read if (r <= 0) { - DEBUG(perror("read");); + DEBUG(perror("error data not available after select");); return E_IO; } return r; diff --git a/flow/src/main/native/posix/flow_jni.c b/flow/src/main/native/posix/flow_jni.c index 9e0ec5e..8ec2aed 100644 --- a/flow/src/main/native/posix/flow_jni.c +++ b/flow/src/main/native/posix/flow_jni.c @@ -50,7 +50,21 @@ JNIEXPORT jlong JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_open */ JNIEXPORT jint JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_readDirect (JNIEnv *env, jclass clazz, jlong config, jobject buffer) { - return 0; + + char* local_buffer = (char*) (*env)->GetDirectBufferAddress(env, buffer); + if (local_buffer == NULL) { + throwException(env, "java/lang/IllegalArgumentException", "ByteBuffer not direct"); + return -1; + } + jlong size = (*env)->GetDirectBufferCapacity(env, buffer); + + int r = serial_read((struct serial_config*) config, local_buffer, (size_t) size); + if (r < 0) { + check(env, r); + return -1; + } + return r; + } /* @@ -97,7 +111,18 @@ JNIEXPORT void JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_cance JNIEXPORT jint JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_writeDirect (JNIEnv *env, jclass clazz, jlong config, jobject buffer, jint size) { - return 0; + char* local_buffer = (char *) (*env)->GetDirectBufferAddress(env, buffer); + if (local_buffer == NULL) { + throwException(env, "java/lang/IllegalArgumentException", "ByteBuffer not direct"); + return -1; + } + + int r = serial_write((struct serial_config*) config, local_buffer, (size_t) size); + if (r < 0) { + check(env, r); + return -1; + } + return r; } diff --git a/flow/src/main/scala/com/github/jodersky/flow/SerialManager.scala b/flow/src/main/scala/com/github/jodersky/flow/SerialManager.scala index 47c74a1..b6d1e74 100644 --- a/flow/src/main/scala/com/github/jodersky/flow/SerialManager.scala +++ b/flow/src/main/scala/com/github/jodersky/flow/SerialManager.scala @@ -3,14 +3,16 @@ package com.github.jodersky.flow import scala.util.Failure import scala.util.Success import scala.util.Try - import com.github.jodersky.flow.internal.SerialConnection - import Serial.CommandFailed import Serial.Open import akka.actor.Actor import akka.actor.ActorLogging import akka.actor.actorRef2Scala +import akka.actor.OneForOneStrategy +import akka.actor.OneForOneStrategy +import akka.actor.SupervisorStrategy._ +import scala.concurrent.duration._ /** * Entry point to the serial API. Actor that manages serial port creation. Once opened, a serial port is handed over to @@ -21,6 +23,10 @@ class SerialManager extends Actor with ActorLogging { import SerialManager._ import context._ + override val supervisorStrategy = OneForOneStrategy() { + case _: Exception => Stop + } + def receive = { case open @ Open(port, settings, bufferSize) => Try { SerialConnection.open(port, settings) diff --git a/flow/src/main/scala/com/github/jodersky/flow/SerialOperator.scala b/flow/src/main/scala/com/github/jodersky/flow/SerialOperator.scala index fd02577..0592ae0 100644 --- a/flow/src/main/scala/com/github/jodersky/flow/SerialOperator.scala +++ b/flow/src/main/scala/com/github/jodersky/flow/SerialOperator.scala @@ -48,6 +48,10 @@ class SerialOperator(connection: SerialConnection, bufferSize: Int, client: Acto client ! Closed context stop self } + + case Terminated(`client`) => { + context stop self + } //go down with reader thread case ReaderDied(ex) => throw ex -- cgit v1.2.3