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.