mturk 2005/04/18 09:22:23
Modified: jni/java/org/apache/tomcat/jni Socket.java
jni/native/src network.c
Log:
Added sendfilet (sendfile with timeout) function to skip the need
to call two additional JNI calls in case we wish nonblocking sendifle.
Revision Changes Path
1.11 +26 -1
jakarta-tomcat-connectors/jni/java/org/apache/tomcat/jni/Socket.java
Index: Socket.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat-connectors/jni/java/org/apache/tomcat/jni/Socket.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- Socket.java 16 Apr 2005 15:07:53 -0000 1.10
+++ Socket.java 18 Apr 2005 16:22:22 -0000 1.11
@@ -445,4 +445,29 @@
byte[][] trailers, long offset,
int len, int flags);
+ /**
+ * Send a file from an open file descriptor to a socket, along with
+ * optional headers and trailers, with a timeout.
+ * <br />
+ * This functions acts like a blocking write by default. To change
+ * this behavior, use apr_socket_timeout_set() or the
+ * APR_SO_NONBLOCK socket option.
+ * The number of bytes actually sent is stored in the len parameter.
+ * The offset parameter is passed by reference for no reason; its
+ * value will never be modified by the apr_socket_sendfile() function.
+ * @param sock The socket to which we're writing
+ * @param file The open file from which to read
+ * @param headers Array containing the headers to send
+ * @param trailers Array containing the trailers to send
+ * @param offset Offset into the file where we should begin writing
+ * @param len Number of bytes to send from the file
+ * @param flags APR flags that are mapped to OS specific flags
+ * @return Number of bytes actually sent, including headers,
+ * file, and trailers
+ *
+ */
+ public static native int sendfilet(long sock, long file, byte [][]
headers,
+ byte[][] trailers, long offset,
+ int len, int flags, long timeout);
+
}
1.13 +73 -0 jakarta-tomcat-connectors/jni/native/src/network.c
Index: network.c
===================================================================
RCS file: /home/cvs/jakarta-tomcat-connectors/jni/native/src/network.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- network.c 18 Apr 2005 12:31:13 -0000 1.12
+++ network.c 18 Apr 2005 16:22:23 -0000 1.13
@@ -577,3 +577,76 @@
else
return -(jint)ss;
}
+
+TCN_IMPLEMENT_CALL(jint, Socket, sendfilet)(TCN_STDARGS, jlong sock,
+ jlong file,
+ jobjectArray headers,
+ jobjectArray trailers,
+ jlong offset, jint len,
+ jint flags, jlong timeout)
+{
+ apr_socket_t *s = J2P(sock, apr_socket_t *);
+ apr_file_t *f = J2P(file, apr_file_t *);
+ jsize nh = 0;
+ jsize nt = 0;
+ jsize i;
+ struct iovec hvec[APR_MAX_IOVEC_SIZE];
+ struct iovec tvec[APR_MAX_IOVEC_SIZE];
+ jobject hba[APR_MAX_IOVEC_SIZE];
+ jobject tba[APR_MAX_IOVEC_SIZE];
+ apr_off_t off = (apr_off_t)offset;
+ apr_size_t written = (apr_size_t)len;
+ apr_hdtr_t hdrs;
+ apr_status_t ss;
+ apr_interval_time_t t;
+
+ UNREFERENCED(o);
+ TCN_ASSERT(sock != 0);
+ TCN_ASSERT(file != 0);
+
+ if (headers)
+ nh = (*e)->GetArrayLength(e, headers);
+ if (trailers)
+ nt = (*e)->GetArrayLength(e, trailers);
+ /* Check for overflow */
+ if (nh >= APR_MAX_IOVEC_SIZE || nt >= APR_MAX_IOVEC_SIZE)
+ return (jint)(-APR_ENOMEM);
+ if ((ss = apr_socket_timeout_get(s, &t)) != APR_SUCCESS)
+ return -(jint)ss;
+ if ((ss = apr_socket_timeout_set(s, J2T(timeout))) != APR_SUCCESS)
+ return -(jint)ss;
+
+ for (i = 0; i < nh; i++) {
+ hba[i] = (*e)->GetObjectArrayElement(e, headers, i);
+ hvec[i].iov_len = (*e)->GetArrayLength(e, hba[i]);
+ hvec[i].iov_base = (*e)->GetByteArrayElements(e, hba[i], NULL);
+ }
+ for (i = 0; i < nt; i++) {
+ tba[i] = (*e)->GetObjectArrayElement(e, trailers, i);
+ tvec[i].iov_len = (*e)->GetArrayLength(e, tba[i]);
+ tvec[i].iov_base = (*e)->GetByteArrayElements(e, tba[i], NULL);
+ }
+ hdrs.headers = &hvec[0];
+ hdrs.numheaders = nh;
+ hdrs.trailers = &tvec[0];
+ hdrs.numtrailers = nt;
+
+ ss = apr_socket_sendfile(s, f, &hdrs, &off, &written,
(apr_int32_t)flags);
+ /* Resore the original timeout */
+ apr_socket_timeout_set(s, t);
+
+ for (i = 0; i < nh; i++) {
+ (*e)->ReleaseByteArrayElements(e, hba[i], hvec[i].iov_base,
JNI_ABORT);
+ }
+
+ for (i = 0; i < nt; i++) {
+ (*e)->ReleaseByteArrayElements(e, tba[i], tvec[i].iov_base,
JNI_ABORT);
+ }
+ /* Return Number of bytes actually sent,
+ * including headers, file, and trailers
+ */
+ if (ss == APR_SUCCESS)
+ return (jint)written;
+ else
+ return -(jint)ss;
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]