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 15:31:53 +0100
On 09/05/11 12:59, Philip Martin wrote:
> Yes, that would work. An alternative would be to deregister the pool
Here is a version that does this. It's tested with the existing tests,
[[[
This is particularly needed for the Python bindings. The PyObject
--- .../swig/python/libsvn_swig_py/swigutil_py.c | 4 ++- subversion/libsvn_subr/stream.c | 26 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 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..dd625a2 100644 --- a/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c +++ b/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c @@ -2123,7 +2123,9 @@ svn_swig_py_make_stream(PyObject *py_io, apr_pool_t *pool) svn_stream_set_read(stream, read_handler_pyio); svn_stream_set_write(stream, write_handler_pyio); svn_stream_set_close(stream, close_handler_pyio); - Py_INCREF(py_io); + Py_INCREF(py_io); /* this will be decremented in the + close_handler_pyio, which will be called when + the pool containing this stream is cleared. */ return stream; } diff --git a/subversion/libsvn_subr/stream.c b/subversion/libsvn_subr/stream.c index f03f963..c7d6e41 100644 --- a/subversion/libsvn_subr/stream.c +++ b/subversion/libsvn_subr/stream.c @@ -54,11 +54,33 @@ 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 */ }; /*** Generic streams. ***/ +static apr_status_t +close_stream_cleanup(void *stream) +{ + apr_status_t apr_err = APR_SUCCESS; + svn_error_t *err; + + /* This is used to close the stream if the pool is being destroyed. + It was first introduced for the Python API, to allow implicit + closing. + */ + + err = svn_stream_close(stream); + if (err) + { + apr_err = err->apr_err; + svn_error_clear(err); + } + + return apr_err; +} + svn_stream_t * svn_stream_create(void *baton, apr_pool_t *pool) { @@ -73,6 +95,9 @@ svn_stream_create(void *baton, apr_pool_t *pool) stream->mark_fn = NULL; stream->seek_fn = NULL; stream->buffered_fn = NULL; + stream->pool = pool; + apr_pool_pre_cleanup_register(stream->pool, stream, + close_stream_cleanup); return stream; } @@ -195,6 +220,7 @@ svn_stream_buffered(svn_stream_t *stream) svn_error_t * svn_stream_close(svn_stream_t *stream) { + apr_pool_cleanup_kill(stream->pool, stream, close_stream_cleanup); if (stream->close_fn == NULL) return SVN_NO_ERROR; return stream->close_fn(stream->baton); ]]] -- 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 16:32:59 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.