Author: brane
Date: Tue Jan 8 16:55:31 2019
New Revision: 1850774
URL: http://svn.apache.org/viewvc?rev=1850774&view=rev
Log:
Invent a model of asynchronous operations in SVN++.
[in subversion/bindings/cxx]
* README: Document a warning about the current async op model.
* svnxx/client/context.hpp
(detail::context_ptr): Make this a shared pointer because asynchronous
operations have to hold on to a weak reference to the context.
(detail::weak_context_ptr): New.
* svnxx/client/status.hpp: Don't include <future>, use detail/future.hpp.
(client::status): Pass revision by const-reference. Update docstring.
(client::async::status): New.
* svnxx/detail/future.hpp: New. Provides std::future-like tools for SVN++.
* src/future.cpp,
src/private/future_private.hpp: New.
* src/private/client_context_private.hpp
(impl::unwrap): Return a shared pointer to the client context.
* src/private.hpp: Include private/future_private.hpp.
* src/client_status.cpp
(impl::(anon)::status_func): Moved here so that it can be used from
impl::status. Check that the wrapped callback functor is not null
before invoking it.
(impl::status): New; common implementation for the status operation.
(client::status): Use impl::status. Keep the client context alive.
(client::async::status): New.
* tests/test_client_status.cpp
(working_copy_root, status_callback): Move to anonymous scope.
(async_example): New test case.
Added:
subversion/trunk/subversion/bindings/cxx/include/svnxx/detail/future.hpp
(with props)
subversion/trunk/subversion/bindings/cxx/src/future.cpp (with props)
subversion/trunk/subversion/bindings/cxx/src/private/future_private.hpp
(with props)
Modified:
subversion/trunk/subversion/bindings/cxx/README
subversion/trunk/subversion/bindings/cxx/include/svnxx/client/context.hpp
subversion/trunk/subversion/bindings/cxx/include/svnxx/client/status.hpp
subversion/trunk/subversion/bindings/cxx/src/client_status.cpp
subversion/trunk/subversion/bindings/cxx/src/private.hpp
subversion/trunk/subversion/bindings/cxx/src/private/client_context_private.hpp
subversion/trunk/subversion/bindings/cxx/tests/test_client_status.cpp
Modified: subversion/trunk/subversion/bindings/cxx/README
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/README?rev=1850774&r1=1850773&r2=1850774&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/README (original)
+++ subversion/trunk/subversion/bindings/cxx/README Tue Jan 8 16:55:31 2019
@@ -129,3 +129,19 @@ with the single header file
.../src/aprwrap.hpp
importing all relevant headers from that directory.
+
+====================================================================
+
+IMPLEMENTATION NOTES
+====================
+
+Asynchronous Operations (TODO)
+------------------------------
+
+In the current model of asyncrhonous operations, we do not protect
+against using the same svn_client_ctx_t object from multiple
+threads. This _should_ be safe as long as the callback
+implementations are aware of it, but we should consider changing the
+design so that whilst svn::client::context can be shared, we create
+the actual svn_client_ctx_t on the fly for each operation --
+similarly to how we create a the scratch pool.
Modified:
subversion/trunk/subversion/bindings/cxx/include/svnxx/client/context.hpp
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/include/svnxx/client/context.hpp?rev=1850774&r1=1850773&r2=1850774&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/include/svnxx/client/context.hpp
(original)
+++ subversion/trunk/subversion/bindings/cxx/include/svnxx/client/context.hpp
Tue Jan 8 16:55:31 2019
@@ -34,7 +34,8 @@ namespace client {
namespace detail {
class context;
-using context_ptr = std::unique_ptr<context>;
+using context_ptr = std::shared_ptr<context>;
+using weak_context_ptr = std::weak_ptr<context>;
} // namespace detail
/**
Modified:
subversion/trunk/subversion/bindings/cxx/include/svnxx/client/status.hpp
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/include/svnxx/client/status.hpp?rev=1850774&r1=1850773&r2=1850774&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/include/svnxx/client/status.hpp
(original)
+++ subversion/trunk/subversion/bindings/cxx/include/svnxx/client/status.hpp
Tue Jan 8 16:55:31 2019
@@ -27,8 +27,8 @@
#include <cstdint>
#include <functional>
-#include <future>
+#include "svnxx/detail/future.hpp"
#include "svnxx/client/context.hpp"
#include "svnxx/depth.hpp"
@@ -82,8 +82,8 @@ inline status_flags operator|(status_fla
}
/**
- * @brief Perform a status walk on @a path.
- * @see svn_client_status6
+ * @ingroup svnxx_client
+ * @brief Perform a status operation on @a path.
* @param ctx the #context object to use for this operation
* @param path the (root) path for the status walk.
* @param rev the revision to use when @c check_out_of_date is set in @a flags
@@ -91,12 +91,45 @@ inline status_flags operator|(status_fla
* @param flags a combination of @c status_flags
* @param callback a function that will be called for each status target
* @warning TODO: Work in progress
+ * @see svn_client_status6
*/
revision::number
status(context& ctx, const char* path,
- revision rev, depth depth, status_flags flags,
+ const revision& rev, depth depth, status_flags flags,
+ status_callback callback);
+
+namespace async {
+
+/**
+ * @ingroup svnxx_client
+ * @brief Perform an asynchronous status operation on @a path.
+ *
+ * Behaves as if svn::client::status() were invoked through
+ * <tt>std::async()</tt>, but also maintains the lifetime of
+ * internal state relevant to the status operation.
+ *
+ * @warning Any callbacks regietered in the context @a ctx, as well
+ * as the status @a callback itself, may be called in the
+ * context of a different thread than the one that created
+ * this asynchronous operation.
+ */
+svnxx::detail::future<revision::number>
+status(std::launch policy, context& ctx, const char* path,
+ const revision& rev, depth depth_, status_flags flags,
+ status_callback callback);
+
+/**
+ * @overload
+ * @ingroup svnxx_client
+ * @note Uses the <tt>std::launch</tt> @a policy set to
+ * <tt>std::launch::async|std::launch::deferred</tt>.
+ */
+svnxx::detail::future<revision::number>
+status(context& ctx, const char* path,
+ const revision& rev, depth depth_, status_flags flags,
status_callback callback);
+} // namespace async
} // namespace client
} // namespace svnxx
} // namespace subversion
Added: subversion/trunk/subversion/bindings/cxx/include/svnxx/detail/future.hpp
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/include/svnxx/detail/future.hpp?rev=1850774&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/include/svnxx/detail/future.hpp
(added)
+++ subversion/trunk/subversion/bindings/cxx/include/svnxx/detail/future.hpp
Tue Jan 8 16:55:31 2019
@@ -0,0 +1,175 @@
+/**
+ * @file svnxx/detail/future.hpp
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ */
+
+#ifndef SVNXX_DETAIL_FUTURE_HPP
+#define SVNXX_DETAIL_FUTURE_HPP
+
+#include <future>
+#include <memory>
+
+namespace apache {
+namespace subversion {
+namespace svnxx {
+namespace detail {
+namespace future_ {
+
+// Forward delcaration of the future result context.
+class result;
+using shared_ptr = std::shared_ptr<result>;
+using unique_ptr = std::unique_ptr<result>;
+
+
+// Base class for template shared_future.
+class shared_future_base
+{
+protected:
+ shared_future_base() noexcept {}
+
+ shared_future_base(const shared_future_base& that)
+ : shared_result(that.shared_result)
+ {}
+
+ shared_future_base(shared_future_base&& that)
+ : shared_result(std::move(that.shared_result))
+ {}
+
+ explicit shared_future_base(shared_ptr shared_result_)
+ : shared_result(shared_result_)
+ {}
+
+private:
+ shared_ptr shared_result;
+};
+
+// Template forward declaration for shared_future constructor.
+template<typename T> class future;
+
+/**
+ * @ingroup svnxx_detail
+ * @brief like <tt>std::shared_future</tt>, but also maintains
+ * internal state relevant to the asynchronous SVN++ operation.
+ */
+template<typename T>
+class shared_future : private std::shared_future<T>,
+ private shared_future_base
+{
+protected:
+ using inherited = std::shared_future<T>;
+
+ shared_future(inherited&& that, shared_ptr shared_result) noexcept
+ : inherited(that), shared_future_base(shared_result)
+ {}
+
+public:
+ shared_future() noexcept {}
+
+ shared_future(const shared_future& that) noexcept
+ : inherited(that), shared_future_base(that)
+ {}
+
+ shared_future(shared_future&& that) noexcept
+ : inherited(std::move(that)), shared_future_base(std::move(that))
+ {}
+
+ shared_future(future<T>&& that) noexcept;
+
+ using inherited::get;
+ using inherited::valid;
+ using inherited::wait;
+ using inherited::wait_for;
+ using inherited::wait_until;
+};
+
+
+// Base class for template future.
+class future_base
+{
+protected:
+ future_base() noexcept;
+ ~future_base() noexcept;
+ future_base(future_base&& that) noexcept;
+ future_base(const future_base&) = delete;
+ explicit future_base(unique_ptr&& unique_result_) noexcept;
+
+ shared_ptr share() noexcept;
+
+private:
+ unique_ptr unique_result;
+};
+
+/**
+ * @ingroup svnxx_detail
+ * @brief like <tt>std::future</tt>, but also maintains internal
+ * state relevant to the asynchronous SVN++ operation.
+ */
+template<typename T>
+class future : private std::future<T>,
+ private future_base
+{
+ // shared_future constructor must be able to access our base classes.
+ friend class shared_future<T>;
+
+protected:
+ using inherited = std::future<T>;
+
+ future(inherited&& that, unique_ptr&& unique_result) noexcept
+ : inherited(std::move(that)), future_base(std::move(unique_result))
+ {}
+
+public:
+ future() noexcept {}
+
+ future(future&& that) noexcept
+ : inherited(std::move(that)), future_base(std::move(that))
+ {}
+
+ shared_future<T> share() noexcept
+ {
+ return shared_future<T>(std::move(*this));
+ }
+
+ using inherited::get;
+ using inherited::valid;
+ using inherited::wait;
+ using inherited::wait_for;
+ using inherited::wait_until;
+};
+
+// Implement the constructor here since it has to see the whole future class.
+template<typename T>
+inline shared_future<T>::shared_future(future<T>&& that) noexcept
+ : inherited(std::move(that)), shared_future_base(that.future_base::share())
+{}
+
+} // namespace future_
+
+template<typename T> using future = future_::future<T>;
+template<typename T> using shared_future = future_::shared_future<T>;
+
+} // namespace detail
+} // namespace svnxx
+} // namespace subversion
+} // namespace apache
+
+#endif // SVNXX_DETAIL_FUTURE_HPP
Propchange:
subversion/trunk/subversion/bindings/cxx/include/svnxx/detail/future.hpp
------------------------------------------------------------------------------
svn:eol-style = native
Modified: subversion/trunk/subversion/bindings/cxx/src/client_status.cpp
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/src/client_status.cpp?rev=1850774&r1=1850773&r2=1850774&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/src/client_status.cpp (original)
+++ subversion/trunk/subversion/bindings/cxx/src/client_status.cpp Tue Jan 8
16:55:31 2019
@@ -31,9 +31,13 @@
namespace apache {
namespace subversion {
namespace svnxx {
-namespace client {
+namespace impl {
namespace {
+using status_notification = client::status_notification;
+using status_callback = client::status_callback;
+using status_flags = client::status_flags;
+
struct status_func
{
status_callback& proxy;
@@ -42,14 +46,17 @@ struct status_func
const svn_client_status_t* /*status*/,
apr_pool_t* /*scratch_pool*/)
{
- try
- {
- const auto self = static_cast<status_func*>(baton);
- self->proxy(path, status_notification{});
- }
- catch (const stop_iteration&)
+ const auto self = static_cast<status_func*>(baton);
+ if (self->proxy)
{
- return impl::iteration_stopped();
+ try
+ {
+ self->proxy(path, status_notification{});
+ }
+ catch (const stop_iteration&)
+ {
+ return impl::iteration_stopped();
+ }
}
return SVN_NO_ERROR;
}
@@ -57,19 +64,16 @@ struct status_func
} // anonymous namespace
revision::number
-status(context& ctx_, const char* path,
- revision rev_, depth depth, status_flags flags,
- status_callback callback_)
+status(svn_client_ctx_t* ctx, const char* path,
+ const svn_opt_revision_t* rev, depth depth_, status_flags flags,
+ status_callback callback_, apr_pool_t* scratch_pool)
{
- const auto& ctx = impl::unwrap(ctx_);
- const auto rev = impl::convert(rev_);
- const apr::pool scratch_pool(&ctx.get_pool());
status_func callback{callback_};
svn_revnum_t result;
impl::checked_call(
- svn_client_status6(&result, ctx.get_ctx(), path, &rev,
- impl::convert(depth),
+ svn_client_status6(&result, ctx, path, rev,
+ impl::convert(depth_),
bool(flags & status_flags::get_all),
bool(flags & status_flags::check_out_of_date),
bool(flags & status_flags::check_working_copy),
@@ -78,11 +82,61 @@ status(context& ctx_, const char* path,
bool(flags & status_flags::depth_as_sticky),
nullptr, // TODO: changelists,
status_func::callback, &callback,
- scratch_pool.get()
- ));
+ scratch_pool));
return revision::number(result);
}
+} // namespace impl
+namespace client {
+
+revision::number
+status(context& ctx_, const char* path,
+ const revision& rev_, depth depth_, status_flags flags,
+ status_callback callback)
+{
+ const auto ctx = impl::unwrap(ctx_);
+ const auto rev = impl::convert(rev_);
+ const apr::pool scratch_pool(&ctx->get_pool());
+ return impl::status(ctx->get_ctx(), path, &rev, depth_, flags,
+ callback, scratch_pool.get());
+}
+
+namespace async {
+
+svnxx::detail::future<revision::number>
+status(std::launch policy, context& ctx_, const char* path,
+ const revision& rev_, depth depth_, status_flags flags,
+ status_callback callback)
+{
+ detail::weak_context_ptr weak_ctx = impl::unwrap(ctx_);
+ return impl::future<revision::number>(
+ std::async(
+ policy,
+ [weak_ctx, path, rev_, depth_, flags, callback]
+ {
+ auto ctx = weak_ctx.lock();
+ if (!ctx)
+ return revision::number::invalid;
+
+ const auto rev = impl::convert(rev_);
+ const apr::pool scratch_pool(&ctx->get_pool());
+
+ return impl::status(ctx->get_ctx(), path, &rev, depth_, flags,
+ callback, scratch_pool.get());
+ }),
+ impl::make_future_result());
+}
+
+svnxx::detail::future<revision::number>
+status(context& ctx_, const char* path,
+ const revision& rev_, depth depth_, status_flags flags,
+ status_callback callback)
+{
+ constexpr std::launch policy = std::launch::async | std::launch::deferred;
+ return status(policy, ctx_, path, rev_, depth_, flags, callback);
+}
+
+} // namespace async
} // namespace client
} // namespace svnxx
} // namespace subversion
Added: subversion/trunk/subversion/bindings/cxx/src/future.cpp
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/src/future.cpp?rev=1850774&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/src/future.cpp (added)
+++ subversion/trunk/subversion/bindings/cxx/src/future.cpp Tue Jan 8 16:55:31
2019
@@ -0,0 +1,52 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ */
+
+#include "private/future_private.hpp"
+
+namespace apache {
+namespace subversion {
+namespace svnxx {
+namespace detail {
+namespace future_ {
+
+future_base::future_base() noexcept {}
+future_base::~future_base() noexcept {}
+
+future_base::future_base(future_base&& that) noexcept
+ : future_base(std::move(that.unique_result))
+{}
+
+future_base::future_base(unique_ptr&& unique_result_) noexcept
+ : unique_result(std::move(unique_result_))
+{}
+
+shared_ptr future_base::share() noexcept
+{
+ return shared_ptr(unique_result.release());
+}
+
+} // namespace future_
+} // namespace detail
+} // namespace svnxx
+} // namespace subversion
+} // namespace apache
Propchange: subversion/trunk/subversion/bindings/cxx/src/future.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Modified: subversion/trunk/subversion/bindings/cxx/src/private.hpp
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/src/private.hpp?rev=1850774&r1=1850773&r2=1850774&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/src/private.hpp (original)
+++ subversion/trunk/subversion/bindings/cxx/src/private.hpp Tue Jan 8
16:55:31 2019
@@ -26,6 +26,7 @@
#include "private/depth_private.hpp"
#include "private/exception_private.hpp"
+#include "private/future_private.hpp"
#include "private/revision_private.hpp"
#include "private/strings_private.hpp"
#include "private/tristate_private.hpp"
Modified:
subversion/trunk/subversion/bindings/cxx/src/private/client_context_private.hpp
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/src/private/client_context_private.hpp?rev=1850774&r1=1850773&r2=1850774&view=diff
==============================================================================
---
subversion/trunk/subversion/bindings/cxx/src/private/client_context_private.hpp
(original)
+++
subversion/trunk/subversion/bindings/cxx/src/private/client_context_private.hpp
Tue Jan 8 16:55:31 2019
@@ -66,14 +66,17 @@ private:
namespace impl {
// TODO: document this
-inline client::detail::context& unwrap(client::context& ctx)
+inline client::detail::context_ptr unwrap(client::context& ctx)
{
struct context_wrapper final : public client::context
{
- using inherited::get;
+ inherited get() const noexcept
+ {
+ return *this;
+ }
};
- return *static_cast<context_wrapper&>(ctx).get();
+ return static_cast<context_wrapper&>(ctx).get();
}
} // namesapce impl
Added: subversion/trunk/subversion/bindings/cxx/src/private/future_private.hpp
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/src/private/future_private.hpp?rev=1850774&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/src/private/future_private.hpp
(added)
+++ subversion/trunk/subversion/bindings/cxx/src/private/future_private.hpp Tue
Jan 8 16:55:31 2019
@@ -0,0 +1,110 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ */
+
+#ifndef SVNXX_PRIVATE_FUTURE_HPP
+#define SVNXX_PRIVATE_FUTURE_HPP
+
+#include "svnxx/detail/future.hpp"
+
+#include "../private/init_private.hpp"
+#include "../aprwrap.hpp"
+
+namespace apache {
+namespace subversion {
+namespace svnxx {
+namespace detail {
+namespace future_ {
+
+
+// Encapsulates a result pool that will contain pool-allocated
+// objects returned from asynchronous operations. Consequently,
+// keeps a reference to the global state that holds the root pool
+// that is the parent of this result pool.
+class result
+{
+public:
+ explicit result(const detail::global_state::ptr& state_)
+ : state(state_),
+ result_pool(state_)
+ {}
+
+ apr::pool& get_pool() noexcept
+ {
+ return result_pool;
+ }
+
+private:
+ const detail::global_state::ptr state;
+ apr::pool result_pool;
+};
+
+} // namespace future_
+} // namespace detail
+namespace impl {
+
+
+// Creates a detail::future_::result pointer for initializing
+// detail::future objects.
+inline detail::future_::unique_ptr
+make_future_result(const detail::global_state::ptr& state)
+{
+ using namespace detail::future_;
+ return unique_ptr(new result(state));
+}
+
+// Creates a null detail::future_::result pointer for cases where we
+// do not need a result pool.
+inline detail::future_::unique_ptr
+make_future_result()
+{
+ return detail::future_::unique_ptr();
+}
+
+
+// Wrapper for detail::future with public constructor.
+template<typename T>
+struct future final : public detail::future_::future<T>
+{
+ using inherited = typename detail::future_::future<T>::inherited;
+ future(inherited that, detail::future_::unique_ptr&& ctx) noexcept
+ : detail::future_::future<T>(std::move(that), std::move(ctx))
+ {}
+};
+
+
+// Wrapper for detail::shared_future with public constructor.
+template<typename T>
+struct shared_future final : public detail::future_::shared_future<T>
+{
+ using inherited = typename detail::future_::shared_future<T>::inherited;
+ shared_future(inherited that, detail::future_::shared_ptr ctx) noexcept
+ : detail::future_::shared_future<T>(std::move(that), ctx)
+ {}
+};
+
+} // namespace impl
+} // namespace svnxx
+} // namespace subversion
+} // namespace apache
+
+#endif // SVNXX_PRIVATE_FUTURE_HPP
Propchange:
subversion/trunk/subversion/bindings/cxx/src/private/future_private.hpp
------------------------------------------------------------------------------
svn:eol-style = native
Modified: subversion/trunk/subversion/bindings/cxx/tests/test_client_status.cpp
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/tests/test_client_status.cpp?rev=1850774&r1=1850773&r2=1850774&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/tests/test_client_status.cpp
(original)
+++ subversion/trunk/subversion/bindings/cxx/tests/test_client_status.cpp Tue
Jan 8 16:55:31 2019
@@ -32,24 +32,40 @@ namespace svn = ::apache::subversion::sv
BOOST_AUTO_TEST_SUITE(client_status,
* boost::unit_test::fixture<init>());
+namespace {
+const char working_copy_root[] = "/Users/brane/src/svn/repos/trunk";
+
+const auto status_callback = [](const char* path,
+ const svn::client::status_notification&)
+ {
+ std::cout << "status on: " << path <<
std::endl;
+ };
+}
+
BOOST_AUTO_TEST_CASE(example,
* boost::unit_test::disabled())
{
- const char working_copy_root[] = "/Users/brane/src/svn/repos/trunk";
-
- const auto callback = [](const char* path,
- const svn::client::status_notification&)
- {
- std::cout << "status on: " << path << std::endl;
- };
svn::client::context ctx;
-
const auto revnum = svn::client::status(ctx, working_copy_root,
svn::revision(),
svn::depth::unknown,
svn::client::status_flags::empty,
- callback);
+ status_callback);
std::cout << "got revision: " << long(revnum) << std::endl;
}
+BOOST_AUTO_TEST_CASE(async_example,
+ * boost::unit_test::disabled())
+{
+ svn::client::context ctx;
+ auto future = svn::client::async::status(ctx, working_copy_root,
+ svn::revision(),
+ svn::depth::unknown,
+ svn::client::status_flags::empty,
+ status_callback);
+ BOOST_TEST(future.valid());
+ future.wait();
+ std::cout << "got revision: " << long(future.get()) << std::endl;
+}
+
BOOST_AUTO_TEST_SUITE_END();