--- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java Wed Apr 11 07:26:35 2012 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java Wed Apr 11 17:12:35 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -374,6 +374,12 @@
*/
private boolean isFirstAppOutputRecord = true;
+ /*
+ * If AppOutputStream needs to delay writes of small packets, we
+ * will use this to store the data until we actually do the write.
+ */
+ private ByteArrayOutputStream heldRecordBuffer = null;
+
//
// CONSTRUCTORS AND INITIALIZATION CODE
//
@@ -654,13 +660,24 @@
//
/*
+ * AppOutputStream calls may need to buffer multiple outbound
+ * application packets.
+ *
+ * All other writeRecord() calls will not buffer, so do not hold
+ * these records.
+ */
+ void writeRecord(OutputRecord r) throws IOException {
+ writeRecord(r, false);
+ }
+
+ /*
* Record Output. Application data can't be sent until the first
* handshake establishes a session.
*
* NOTE: we let empty records be written as a hook to force some
* TCP-level activity, notably handshaking, to occur.
*/
- void writeRecord(OutputRecord r) throws IOException {
+ void writeRecord(OutputRecord r, boolean holdRecord) throws IOException {
/*
* The loop is in case of HANDSHAKE --> ERROR transitions, etc
*/
@@ -731,7 +748,7 @@
try {
if (writeLock.tryLock(getSoLinger(), TimeUnit.SECONDS)) {
try {
- writeRecordInternal(r);
+ writeRecordInternal(r, holdRecord);
} finally {
writeLock.unlock();
}
@@ -779,7 +796,7 @@
} else {
writeLock.lock();
try {
- writeRecordInternal(r);
+ writeRecordInternal(r, holdRecord);
} finally {
writeLock.unlock();
}
@@ -787,11 +804,29 @@
}
}
- private void writeRecordInternal(OutputRecord r) throws IOException {
+ private void writeRecordInternal(OutputRecord r,
+ boolean holdRecord) throws IOException {
+
// r.compress(c);
r.addMAC(writeMAC);
r.encrypt(writeCipher);
- r.write(sockOutput);
+
+ if (holdRecord) {
+ // If we were requested to delay the record due to possibility
+ // of Nagle's being active when finally got to writing, and
+ // it's actually not, we don't really need to delay it.
+ if (getTcpNoDelay()) {
+ holdRecord = false;
+ } else {
+ // We need to hold the record, so let's provide
+ // a per-socket place to do it.
+ if (heldRecordBuffer == null) {
+ // Likely only need 37 bytes.
+ heldRecordBuffer = new ByteArrayOutputStream(40);
+ }
+ }
+ }
+ r.write(sockOutput, holdRecord, heldRecordBuffer);
/*
* Check the sequence number state