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]