changeset 56:958ec7f4180f

8066264: OOM when SPI.writeAndRead with skip Summary: Fixed the case when write buffer is exhausted but there is space to read Reviewed-by: snazarki Contributed-by: alexey.mironov@oracle.com
author snazarki
date Wed, 03 Dec 2014 21:24:03 +0400
parents fdf76602f5b7
children 7531895ef161
files src/share/classes/com/oracle/dio/impl/AbstractPeripheral.java src/share/classes/com/oracle/dio/spibus/impl/SPISlaveImpl.java
diffstat 2 files changed, 11 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/oracle/dio/impl/AbstractPeripheral.java	Mon Dec 01 20:40:49 2014 +0400
+++ b/src/share/classes/com/oracle/dio/impl/AbstractPeripheral.java	Wed Dec 03 21:24:03 2014 +0400
@@ -135,7 +135,7 @@
         }
     }
 
-    protected synchronized void setBusyFlag(boolean newFlag, int exceptionMsgId) throws IllegalArgumentException {
+    protected void setBusyFlag(boolean newFlag, int exceptionMsgId) throws IllegalArgumentException {
         if (busyFlag && newFlag) {
             throw new IllegalStateException(
                 ExceptionMessage.format(exceptionMsgId)
@@ -172,7 +172,7 @@
         if (null != src && src.hasRemaining()) {
             if (src.isDirect()) {
                 tmp = src.slice();
-                if (null != toCompare && toCompare.remaining() < src.remaining()) {
+                if (null != toCompare && toCompare.hasRemaining() && toCompare.remaining() < src.remaining()) {
                     tmp.limit(toCompare.remaining());
                 }
             } else {
--- a/src/share/classes/com/oracle/dio/spibus/impl/SPISlaveImpl.java	Mon Dec 01 20:40:49 2014 +0400
+++ b/src/share/classes/com/oracle/dio/spibus/impl/SPISlaveImpl.java	Wed Dec 03 21:24:03 2014 +0400
@@ -501,6 +501,10 @@
 
                 // if there is nothing to send, use recv buffer as dummy send data
                 if (null == toSend) {
+                    if (null == toRecv) {
+                        // both empty buffers
+                        return xfered;
+                    }
                     toSend = toRecv.slice();
                 }
 
@@ -520,13 +524,6 @@
                     conditionalUnlock();
                 }
 
-
-                if (count_recv) {
-                    xfered += (null == toRecv) ? 0 : toRecv.remaining();
-                } else {
-                    xfered += toSend.remaining();
-                }
-
                 if (null != src) {
                     if (null != localActions) {
                         final ByteBuffer ref = toSend;
@@ -539,6 +536,9 @@
                     }
 
                     try {
+                        if (!count_recv) {
+                            xfered += toSend.remaining();
+                        }
                         src.position(src.position() + toSend.remaining());
                     }catch (IllegalArgumentException e){
                         // the buffer was updated in parallel
@@ -549,7 +549,7 @@
                 }
 
                 if (skip > 0) {
-                    if(null != toRecv) {
+                    if (null != toRecv) {
                         // ability to fit 'skip' bytes was checked above (see if (toSend.remaining() <= skip) )
                         toRecv.position(skip);
                         skip = 0;
@@ -558,6 +558,7 @@
                     }
                 }
                 if (null != toRecv) {
+                    xfered += toRecv.remaining();
                     // transaction requires postponed reverse copying
                     if (null != localActions) {
                         final ByteBuffer to = dst.slice();