jdk/src/solaris/native/sun/nio/ch/sctp/SctpChannelImpl.c
changeset 23575 6fd9136dc579
parent 22631 ac85b05a53f4
--- a/jdk/src/solaris/native/sun/nio/ch/sctp/SctpChannelImpl.c	Mon Mar 24 14:35:32 2014 -0700
+++ b/jdk/src/solaris/native/sun/nio/ch/sctp/SctpChannelImpl.c	Tue Mar 25 09:31:37 2014 +0000
@@ -38,8 +38,7 @@
 #include "sun_nio_ch_sctp_ResultContainer.h"
 #include "sun_nio_ch_sctp_PeerAddrChange.h"
 
-/* sizeof(union sctp_notification */
-#define NOTIFICATION_BUFFER_SIZE 280
+static int SCTP_NOTIFICATION_SIZE = sizeof(union sctp_notification);
 
 #define MESSAGE_IMPL_CLASS              "sun/nio/ch/sctp/MessageInfoImpl"
 #define RESULT_CONTAINER_CLASS          "sun/nio/ch/sctp/ResultContainer"
@@ -463,20 +462,47 @@
         if (msg->msg_flags & MSG_NOTIFICATION) {
             char *bufp = (char*)addr;
             union sctp_notification *snp;
+            jboolean allocated = JNI_FALSE;
 
-            if (!(msg->msg_flags & MSG_EOR) && length < NOTIFICATION_BUFFER_SIZE) {
-                char buf[NOTIFICATION_BUFFER_SIZE];
+            if (rv > SCTP_NOTIFICATION_SIZE) {
+                JNU_ThrowInternalError(env, "should not reach here");
+                return -1;
+            }
+
+            if (!(msg->msg_flags & MSG_EOR) && length < SCTP_NOTIFICATION_SIZE) {
+                char* newBuf;
                 int rvSAVE = rv;
-                memcpy(buf, addr, rv);
-                iov->iov_base = buf + rv;
-                iov->iov_len = NOTIFICATION_BUFFER_SIZE - rv;
+
+                if ((newBuf = malloc(SCTP_NOTIFICATION_SIZE)) == NULL) {
+                    JNU_ThrowOutOfMemoryError(env, "Out of native heap space.");
+                    return -1;
+                }
+                allocated = JNI_TRUE;
+
+                memcpy(newBuf, addr, rv);
+                iov->iov_base = newBuf + rv;
+                iov->iov_len = SCTP_NOTIFICATION_SIZE - rv;
                 if ((rv = recvmsg(fd, msg, flags)) < 0) {
                     handleSocketError(env, errno);
                     return 0;
                 }
-                bufp = buf;
+                bufp = newBuf;
                 rv += rvSAVE;
             }
+#ifdef __sparc
+              else if ((intptr_t)addr & 0x3) {
+                /* the given buffer is not 4 byte aligned */
+                char* newBuf;
+                if ((newBuf = malloc(SCTP_NOTIFICATION_SIZE)) == NULL) {
+                    JNU_ThrowOutOfMemoryError(env, "Out of native heap space.");
+                    return -1;
+                }
+                allocated = JNI_TRUE;
+
+                memcpy(newBuf, addr, rv);
+                bufp = newBuf;
+            }
+#endif
             snp = (union sctp_notification *) bufp;
             if (handleNotification(env, fd, resultContainerObj, snp, rv,
                                    (msg->msg_flags & MSG_EOR),
@@ -484,9 +510,16 @@
                 /* We have received a notification that is of interest to
                    to the Java API. The appropriate notification will be
                    set in the result container. */
+                if (allocated == JNI_TRUE) {
+                    free(bufp);
+                }
                 return 0;
             }
 
+            if (allocated == JNI_TRUE) {
+                free(bufp);
+            }
+
             // set iov back to addr, and reset msg_controllen
             iov->iov_base = addr;
             iov->iov_len = length;