Author: brane Date: Tue Dec 25 21:24:25 2018 New Revision: 1849724 URL: http://svn.apache.org/viewvc?rev=1849724&view=rev Log: Move root pool creation completely to SVN++, because with exceptions, we can report a memory allocation failure to the application.
[in subversion/bindings/cxx] * include/svnxx/exception.hpp: Include <stdexcept>. (svn::allocation_failed): New exception type. * src/init.cpp: Include svnxx/exception.hpp. (handle_failed_allocation): New; failed allocation handler for APR pools. (create_root_pool): New. (context::context): call create_root_pool(). Modified: subversion/trunk/subversion/bindings/cxx/include/svnxx/exception.hpp subversion/trunk/subversion/bindings/cxx/src/init.cpp Modified: subversion/trunk/subversion/bindings/cxx/include/svnxx/exception.hpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/include/svnxx/exception.hpp?rev=1849724&r1=1849723&r2=1849724&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/cxx/include/svnxx/exception.hpp (original) +++ subversion/trunk/subversion/bindings/cxx/include/svnxx/exception.hpp Tue Dec 25 21:24:25 2018 @@ -21,14 +21,11 @@ * @endcopyright */ -#ifndef __cplusplus -#error "This is a C++ header file." -#endif - #ifndef SVNXX_EXCEPTION_HPP #define SVNXX_EXCEPTION_HPP #include <exception> +#include <stdexcept> #include <memory> #include <string> #include <utility> @@ -38,6 +35,23 @@ namespace apache { namespace subversion { namespace svnxx { +/** + * @brief Exception type that will be thrown when memory allocation fails. + */ +class allocation_failed : public std::runtime_error +{ +public: + explicit allocation_failed(const std::string& what_arg) + : std::runtime_error(what_arg) + {} + + explicit allocation_failed(const char* what_arg) + : std::runtime_error(what_arg) + {} + + virtual ~allocation_failed() {} +}; + namespace detail { // Forward declaration of implementation-specific structure class ErrorDescription; Modified: subversion/trunk/subversion/bindings/cxx/src/init.cpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/src/init.cpp?rev=1849724&r1=1849723&r2=1849724&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/cxx/src/init.cpp (original) +++ subversion/trunk/subversion/bindings/cxx/src/init.cpp Tue Dec 25 21:24:25 2018 @@ -23,6 +23,7 @@ #include <sstream> +#include "svnxx/exception.hpp" #include "private/init-private.hpp" #include <apr_general.h> @@ -38,6 +39,38 @@ init::init() namespace detail { +namespace { +int handle_failed_allocation(int) +{ + throw allocation_failed(""); +} + +apr_pool_t* create_root_pool() +{ + apr_allocator_t *allocator; + if (apr_allocator_create(&allocator) || !allocator) + throw allocation_failed("svn++ creating pool allocator"); + + apr_pool_t* root_pool; + apr_pool_create_ex(&root_pool, nullptr, handle_failed_allocation, allocator); + if (!root_pool) + throw allocation_failed("svn++ creating root pool"); + +#if APR_POOL_DEBUG + apr_pool_tag(root_pool, "svn++ root pool"); +#endif + +#if APR_HAS_THREADS + // SVN++ pools are always as thread safe as APR can make them. + apr_thread_mutex_t *mutex; + apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, root_pool); + apr_allocator_mutex_set(allocator, mutex); +#endif + + return root_pool; +} +} // anonymous namespace + std::mutex context::guard; context::weak_ptr context::self; @@ -68,12 +101,7 @@ context::context() << apr_strerror(status, errbuf, sizeof(errbuf) - 1); throw std::runtime_error(message.str()); } - - const auto allocator = svn_pool_create_allocator(true); - root_pool = svn_pool_create_ex(nullptr, allocator); - - // TODO: Check root pool for null. - // TODO: Change allocation-failed handler? + root_pool = create_root_pool(); } context::~context()