This patch adds an apr_file_setaside() function that moves
an apr_file_t from one pool to another without doing any
dup(2) or mmap(2) operations.
The motivation behind this is to provide the foundation for
setting aside small files in core_output_filter()'s keepalive
code without having to read in their contents.
Can someone with a win32 build environment please let me know
if the win32 version looks okay?
Thanks,
--Brian
Index: include/apr_file_io.h
===================================================================
RCS file: /home/cvs/apr/include/apr_file_io.h,v
retrieving revision 1.128
diff -u -r1.128 apr_file_io.h
--- include/apr_file_io.h 29 Jun 2002 22:53:30 -0000 1.128
+++ include/apr_file_io.h 29 Jun 2002 23:55:20 -0000
@@ -458,6 +458,21 @@
apr_pool_t *p);
/**
+ * move the specified file descriptor to a new pool
+ * @param new_file Pointer in which to return the new apr_file_t
+ * @param old_file The file to move
+ * @param p The pool to which the descriptor is to be moved
+ * @remark Unlike apr_file_dup2(), this function doesn't do an
+ * OS dup() operation on the underlying descriptor; it just
+ * moves the descriptor's apr_file_t wrapper to a new pool.
+ * @remark The new pool need not be an ancestor of old_file's pool.
+ * @remark After calling this function, old_file may not be used
+ */
+APR_DECLARE(apr_status_t) apr_file_setaside(apr_file_t **new_file,
+ apr_file_t *old_file,
+ apr_pool_t *p);
+
+/**
* Move the read/write file offset to a specified byte within a file.
* @param thefile The file descriptor
* @param where How to move the pointer, one of:
Index: file_io/unix/filedup.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/filedup.c,v
retrieving revision 1.48
diff -u -r1.48 filedup.c
--- file_io/unix/filedup.c 8 Jun 2002 22:32:11 -0000 1.48
+++ file_io/unix/filedup.c 29 Jun 2002 23:55:20 -0000
@@ -148,3 +148,38 @@
#endif
}
+APR_DECLARE(apr_status_t) apr_file_setaside(apr_file_t **new_file,
+ apr_file_t *old_file,
+ apr_pool_t *p)
+{
+ *new_file = (apr_file_t *)apr_palloc(p, sizeof(apr_file_t));
+ memcpy(*new_file, old_file, sizeof(apr_file_t));
+ (*new_file)->pool = p;
+ if (old_file->buffered) {
+ (*new_file)->buffer = apr_palloc(p, APR_FILE_BUFSIZE);
+ if (old_file->direction == 1) {
+ memcpy((*new_file)->buffer, old_file->buffer, old_file->bufpos);
+ }
+ else {
+ memcpy((*new_file)->buffer, old_file->buffer, old_file->dataRead);
+ }
+ if (old_file->thlock) {
+ apr_thread_mutex_create(&((*new_file)->thlock),
+ APR_THREAD_MUTEX_DEFAULT, p);
+ apr_thread_mutex_destroy(old_file->thlock);
+ }
+ }
+ if (old_file->fname) {
+ (*new_file)->fname = apr_pstrdup(p, old_file->fname);
+ }
+ if (!(old_file->flags & APR_FILE_NOCLEANUP)) {
+ apr_pool_cleanup_register(p, (void *)(*new_file),
+ apr_unix_file_cleanup,
+ apr_unix_file_cleanup);
+ }
+
+ old_file->filedes = -1;
+ apr_pool_cleanup_kill(old_file->pool, (void *)old_file,
+ apr_unix_file_cleanup);
+ return APR_SUCCESS;
+}
Index: file_io/win32/filedup.c
===================================================================
RCS file: /home/cvs/apr/file_io/win32/filedup.c,v
retrieving revision 1.45
diff -u -r1.45 filedup.c
--- file_io/win32/filedup.c 20 Mar 2002 08:54:42 -0000 1.45
+++ file_io/win32/filedup.c 29 Jun 2002 23:55:20 -0000
@@ -150,3 +150,38 @@
#endif /* !defined(_WIN32_WCE) */
}
+APR_DECLARE(apr_status_t) apr_file_setaside(apr_file_t **new_file,
+ apr_file_t *old_file,
+ apr_pool_t *p)
+{
+ *new_file = (apr_file_t *)apr_palloc(p, sizeof(apr_file_t));
+ memcpy(*new_file, old_file, sizeof(apr_file_t));
+ (*new_file)->pool = p;
+ if (old_file->buffered) {
+ (*new_file)->buffer = apr_palloc(p, APR_FILE_BUFSIZE);
+ if (old_file->direction == 1) {
+ memcpy((*new_file)->buffer, old_file->buffer, old_file->bufpos);
+ }
+ else {
+ memcpy((*new_file)->buffer, old_file->buffer, old_file->dataRead);
+ }
+ if (old_file->thlock) {
+ apr_thread_mutex_create(&((*new_file)->thlock),
+ APR_THREAD_MUTEX_DEFAULT, p);
+ apr_thread_mutex_destroy(old_file->thlock);
+ }
+ }
+ if (old_file->fname) {
+ (*new_file)->fname = apr_pstrdup(p, old_file->fname);
+ }
+ if (!(old_file->flags & APR_FILE_NOCLEANUP)) {
+ apr_pool_cleanup_register(p, (void *)(*new_file),
+ file_cleanup,
+ file_cleanup);
+ }
+
+ old_file->filedes = -1;
+ apr_pool_cleanup_kill(old_file->pool, (void *)old_file,
+ file_cleanup);
+ return APR_SUCCESS;
+}