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;
+}

Reply via email to