Re: AW: Python bindings: Use of svn_swig_py_make_stream() - avoiding leaking fds
From: Nick Piper <nick.piper_at_logica.com>
Date: Mon, 9 May 2011 18:19:54 +0100
This version:
[[[
This is particularly needed for the Python bindings. The PyObject
---
.../swig/python/libsvn_swig_py/swigutil_py.c | 1 +
subversion/include/svn_io.h | 7 +++
subversion/libsvn_subr/stream.c | 49
++++++++++++++++----
3 files changed, 48 insertions(+), 9 deletions(-)
diff --git
a/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
b/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
index d8b9c08..fff5e90 100644
--- a/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
+++ b/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
@@ -2124,6 +2124,7 @@ svn_swig_py_make_stream(PyObject *py_io,
apr_pool_t *pool)
svn_stream_set_write(stream, write_handler_pyio);
svn_stream_set_close(stream, close_handler_pyio);
Py_INCREF(py_io);
+ svn_stream_close_on_cleanup(stream);
return stream;
}
diff --git a/subversion/include/svn_io.h b/subversion/include/svn_io.h
index c518d24..686f462 100644
--- a/subversion/include/svn_io.h
+++ b/subversion/include/svn_io.h
@@ -1092,6 +1092,13 @@ svn_stream_write(svn_stream_t *stream,
svn_error_t *
svn_stream_close(svn_stream_t *stream);
+/** Set @a stream to be automatically closed when pool containing it is
cleared
+ *
+ * @since New in 1.7
+ */
+void
+svn_stream_close_on_cleanup(svn_stream_t *stream);
+
/** Reset a generic stream back to its origin. E.g. On a file this would be
* implemented as a seek to position 0). This function returns a
* #SVN_ERR_STREAM_RESET_NOT_SUPPORTED error when the stream doesn't
diff --git a/subversion/libsvn_subr/stream.c
b/subversion/libsvn_subr/stream.c
index f03f963..0d4cfa5 100644
--- a/subversion/libsvn_subr/stream.c
+++ b/subversion/libsvn_subr/stream.c
@@ -54,6 +54,7 @@ struct svn_stream_t {
svn_io_mark_fn_t mark_fn;
svn_io_seek_fn_t seek_fn;
svn_io_buffered_fn_t buffered_fn;
+ apr_pool_t *pool; /* to allow us to deregister clean up functions */
};
@@ -73,9 +74,48 @@ svn_stream_create(void *baton, apr_pool_t *pool)
stream->mark_fn = NULL;
stream->seek_fn = NULL;
stream->buffered_fn = NULL;
+ stream->pool = pool;
return stream;
}
+static svn_error_t *
+svn_stream_close_body(svn_stream_t *stream)
+{
+ if (stream->close_fn == NULL)
+ return SVN_NO_ERROR;
+ return stream->close_fn(stream->baton);
+}
+
+static apr_status_t
+close_stream_cleanup(void *stream)
+{
+ apr_status_t apr_err = APR_SUCCESS;
+ svn_error_t *err;
+
+ err = svn_stream_close_body(stream);
+ if (err)
+ {
+ apr_err = err->apr_err;
+ svn_error_clear(err);
+ }
+
+ return apr_err;
+}
+
+svn_error_t *
+svn_stream_close(svn_stream_t *stream)
+{
+ apr_pool_cleanup_kill(stream->pool, stream, close_stream_cleanup);
+ return svn_stream_close_body(stream);
+}
+
+void
+svn_stream_close_on_cleanup(svn_stream_t *stream)
+{
+ apr_pool_cleanup_register(stream->pool, stream,
+ close_stream_cleanup,
+ apr_pool_cleanup_null);
+}
void
svn_stream_set_baton(svn_stream_t *stream, void *baton)
@@ -193,15 +233,6 @@ svn_stream_buffered(svn_stream_t *stream)
}
svn_error_t *
-svn_stream_close(svn_stream_t *stream)
-{
- if (stream->close_fn == NULL)
- return SVN_NO_ERROR;
- return stream->close_fn(stream->baton);
-}
-
-
-svn_error_t *
svn_stream_printf(svn_stream_t *stream,
apr_pool_t *pool,
const char *fmt,
]]]
--
Sorry for this disclaimer:
Think green - keep it on the screen.
This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Thank you.
Received on 2011-05-09 19:20:51 CEST
|
This is an archived mail posted to the Subversion Dev mailing list.
This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.