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()


Reply via email to