src/share/classes/com/oracle/dio/uart/impl/UARTImpl.java

Print this page

        

@@ -84,11 +84,10 @@
 
     private int receiveTriggerLevel;
     private int inputTimeout;
     private Timer receiveTimer;
 
-    private InputRoundListener<UART, ByteBuffer> iRL;
 
     UARTImpl(DeviceDescriptor<UART> dscr, int mode)
                                 throws DeviceNotFoundException, InvalidDeviceConfigException, UnsupportedAccessModeException{
         super(dscr, mode);
 

@@ -130,12 +129,11 @@
         eventListeners = new Hashtable<Integer, UARTEventListener>();
         initPowerManagement();
     }
 
     private InputRoundListener getLocalInputRoundListener(){
-        if(iRL == null){
-            iRL = new InputRoundListener<UART, ByteBuffer>() {
+        return new InputRoundListener<UART, ByteBuffer>() {
                 @Override
                 public void inputRoundCompleted(RoundCompletionEvent<UART, ByteBuffer> event) {
                     synchronized(synchReadLock){
                         synchReadLock.notifyAll();
                     }

@@ -147,12 +145,10 @@
                         synchReadLock.notifyAll();
                     }
                 }
             };
         }
-        return iRL;
-    }
 
     private void startReceiveTimer(){
 
         if(receiveTimer != null){
             receiveTimer.cancel();

@@ -264,16 +260,16 @@
                     because of that no slice() call is necessary, the following is redundand:
 
                     int bytesReaden = read0(buffer.slice());
 
                 */
+                int tmpPos = buffer.position();
                 int bytesRead = read0(buffer);
                 try{
-                    buffer.position(buffer.position() + bytesRead);
-                }catch(IllegalArgumentException e){
-                    //buffer.position() + bytesRead < 0 (not expected) or buffer.position() + bytesRead > limit
-                    buffer.position(buffer.limit());
+                    shiftBufferPosition(buffer, tmpPos + bytesRead);
+                }catch(IOException e){
+
                 }
 
                 if(!buffer.hasRemaining() || ( receiveTriggerLevel !=0 && (buffer.position() - readBuffersPositions[readBufferIdx]) >= receiveTriggerLevel) || (-1 == bytesProcessed)){
                     RoundCompletionEvent<UART,ByteBuffer> rcEvent =
                         new RoundCompletionEvent(this, buffer, buffer.position() - readBuffersPositions[readBufferIdx]);

@@ -478,10 +474,20 @@
         UARTEventHandler.getInstance().addEventListener(eventId, this);
         setEventListener0(eventId);
     }
 
     private void unsubscribe(int eventId){
+        /*
+         * 2 listeners work withINPUT_DATA_AVAILABLE :
+         * user defined + internal for filling buffers
+         */
+        if(eventId == UARTEvent.INPUT_DATA_AVAILABLE){
+            if(inRoundListener != null || eventListeners.get(eventId) != null){
+                return;
+            }
+        }
+
         UARTEventHandler.getInstance().removeEventListener(eventId, this);
         removeEventListener0(eventId);
     }
     /**
      * Sets the parity.

@@ -538,13 +544,12 @@
      */
     @Override
     public synchronized void stopWriting() throws IOException, UnavailableDeviceException, ClosedDeviceException{
         checkOpen();
         if (isWriting){
-            unsubscribe(UARTEvent.OUTPUT_BUFFER_EMPTY);
-
             outRoundListener = null;
+            unsubscribe(UARTEvent.OUTPUT_BUFFER_EMPTY);
             writeBuffers[0] = writeBuffers[1] = null;
             stopWriting0();
             isWriting = false;
         }
     }

@@ -598,12 +603,12 @@
       */
     @Override
     public synchronized void stopReading() throws IOException, UnavailableDeviceException, ClosedDeviceException{
         checkOpen();
         if (inRoundListener != null){
-            unsubscribe(UARTEvent.INPUT_DATA_AVAILABLE);
             inRoundListener = null;
+            unsubscribe(UARTEvent.INPUT_DATA_AVAILABLE);
             readBuffers[0] = readBuffers[1] = null;
             stopReading0();
         }
     }
 

@@ -641,36 +646,54 @@
      * Reads a sequence of bytes from this UART into the given buffer.
      */
     @Override
     public int read(ByteBuffer dst) throws IOException,
             UnavailableDeviceException, ClosedDeviceException{
+        int ret;
+
+        synchronized(handle){
+
         if (dst == null){
             throw new NullPointerException(
                 ExceptionMessage.format(ExceptionMessage.UART_NULL_DST)
             );
         }
 
-        int ret = dst.position();
         if(!dst.hasRemaining()){
-            return 0;
+                ret = 0;
         }else{
-            startReceiveTimer();
+
+                ret = dst.position();
+                /*read all data available*/
+                int readRes = read0(dst);
+                shiftBufferPosition(dst, ret + readRes);
+                if(UARTEventHandler.getInstance().isDispatchThread() ){
+                    /*
+                        the user calls read() from the event callback,
+                        exit immediatelly
+                     */
+                    ret = readRes;
+                }else{
+                    /*
+                        start asynch read with timer
+                    */
+                    if(dst.hasRemaining()){
             startReading(dst, getLocalInputRoundListener());
             synchronized(synchReadLock){
                 try{
-                    synchReadLock.wait();
+                                synchReadLock.wait(inputTimeout);
                 }catch(InterruptedException iE){
                     throw new IOException();
-                }finally{
-                    stopReceiveTimer();
-                }
             }
+                        } //synch
             stopReading();
-
             ret = dst.position() - ret;
         }
-        return ret==0?-1:ret ;
+                }// else if isDispatchThread()
+            }//if(dst.hasRemaining())
+        }//synch handle
+        return ret==0?-1:ret;
     }
 
     /**
      * Writes a sequence of bytes to this UART from the given buffer.
      */