Skip to content

Commit

Permalink
Remove obsolete APIs from task.hpp (#112)
Browse files Browse the repository at this point in the history
* Remove obsolete APIs from task.hpp

Several cancellation-related APIs have been removed from Windows PPL:
- is_task_cancellation_requested
- run_with_cancellation_token

Remove these are related code from task.hpp.

* Remove cancelation scope code too
  • Loading branch information
bheath-adobe authored Apr 9, 2024
1 parent a2a5264 commit feb4b46
Showing 1 changed file with 1 addition and 159 deletions.
160 changes: 1 addition & 159 deletions adobe/task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,11 @@ cancellation_token_source <http://msdn.microsoft.com/en-us/library/hh749985.aspx
cancellation_token <http://msdn.microsoft.com/en-us/library/hh749975.aspx>
cancellation_token_registration <http://msdn.microsoft.com/en-us/library/hh750057.aspx>
task_canceled <http://msdn.microsoft.com/en-us/library/hh750110.aspx>
is_task_cancellation_requested <http://msdn.microsoft.com/en-us/library/hh750070.aspx>
cancel_current_task <http://msdn.microsoft.com/en-us/library/hh749945.aspx>
run_with_cancellation_token <http://msdn.microsoft.com/en-us/library/hh749944.aspx>
For detailed documentation on using this library see:
<http://msdn.microsoft.com/en-us/library/dd984117.aspx>
There are also two additions:
cancelable_function
make_cancelable
*/

/**************************************************************************************************/
Expand All @@ -65,8 +59,6 @@ using concurrency::cancel_current_task;
using concurrency::cancellation_token;
using concurrency::cancellation_token_registration;
using concurrency::cancellation_token_source;
using concurrency::is_task_cancellation_requested;
using concurrency::run_with_cancellation_token;
using concurrency::task_canceled;

#else
Expand Down Expand Up @@ -102,7 +94,7 @@ struct cancel_state {
template <typename F> // F models void ()
cancellation_token_registration register_callback(F f) {
/*
Avoid heap oerations in the lock by inserting the element in a temporary list then
Avoid heap operations in the lock by inserting the element in a temporary list then
splicing that list into the callback_list_ under the lock.
*/
list_type list;
Expand Down Expand Up @@ -195,72 +187,6 @@ inline bool operator!=(const cancellation_token& x, const cancellation_token& y)

/**************************************************************************************************/

namespace details {

/**************************************************************************************************/

struct cancellation_scope;

/*
REVISIT (sparent) : The thread local implementation should be the default implementation.
The pthread implementation is for current Mac/iOS platforms. Look at what it would take
to use boost instead of posix for OS X.
*/

#if defined(_MSC_VER) && (1800 <= _MSC_VER)

template <typename T = void> // placeholder to allow header only library
cancellation_scope*& get_cancellation_scope_() {
__declspec(thread) static cancellation_scope* result = nullptr;
return result;
}


inline cancellation_scope* get_cancellation_scope() { return get_cancellation_scope_(); }


inline void set_cancellation_scope(cancellation_scope* scope) { get_cancellation_scope_() = scope; }

#else

template <typename T> // placeholder to allow header only library
pthread_key_t get_cancellation_key() {
static pthread_key_t cancellation_key = 0; // aggregate initialized
int r = pthread_key_create(&cancellation_key, 0); // execute once
(void)r; // avoid unused arg warning from above
return cancellation_key;
}

inline cancellation_scope* get_cancellation_scope() {
return static_cast<cancellation_scope*>(pthread_getspecific(get_cancellation_key<void>()));
}


inline void set_cancellation_scope(cancellation_scope* scope) {
pthread_setspecific(get_cancellation_key<void>(), scope);
}

#endif

struct cancellation_scope {
cancellation_scope(cancellation_token token) : token_(std::move(token)) {
prior_ = get_cancellation_scope();
set_cancellation_scope(this);
}

~cancellation_scope() { set_cancellation_scope(prior_); }

cancellation_scope* prior_;
const cancellation_token& token_;
};

/**************************************************************************************************/

} // namespace details

/**************************************************************************************************/

class cancellation_token_source {
public:
cancellation_token_source() : state_(std::make_shared<details::cancel_state>()) {}
Expand Down Expand Up @@ -296,98 +222,14 @@ class task_canceled : public std::exception {

/**************************************************************************************************/

inline bool is_task_cancellation_requested() {
const details::cancellation_scope* scope = details::get_cancellation_scope();
return scope ? scope->token_.is_canceled() : false;
}

[[noreturn]] inline void cancel_current_task() { throw task_canceled(); }

/*!
To be compatible with PPL, this function does nothing if the token is canceled before the
function is executed.
*/

template <typename F> // F models void ()
inline void run_with_cancellation_token(const F& f, cancellation_token token) {
details::cancellation_scope scope(std::move(token));
if (!is_task_cancellation_requested())
f();
}

/**************************************************************************************************/

#endif

/**************************************************************************************************/

/*!
A function object that will execute f with the given cancellation_token in a
run_with_cancellation_token() context. If cancelation is already requested then
task_canceled is thrown and f is not executed.
*/

template <typename F, typename SIG>
class cancelable_function;
template <typename F, typename R, typename... Arg>
class cancelable_function<F, R(Arg...)> {
public:
typedef R result_type;

cancelable_function(F f, cancellation_token token)
: function_(std::move(f)), token_(std::move(token)) {}

R operator()(Arg&&... arg) const {
std::optional<R> r;

run_with_cancellation_token([&] { r = function_(std::forward<Arg>(arg)...); }, token_);

if (!r)
cancel_current_task();
return std::move(r.get());
}

private:
F function_;
cancellation_token token_;
};

template <typename F, typename... Arg>
class cancelable_function<F, void(Arg...)> {
public:
typedef void result_type;

cancelable_function(F f, cancellation_token token)
: function_(std::move(f)), token_(std::move(token)) {}

void operator()(Arg&&... arg) const {
bool executed = false;

run_with_cancellation_token(
[&] {
executed = true;
function_(std::forward<Arg>(arg)...);
},
token_);

if (!executed)
cancel_current_task();
}

private:
F function_;
cancellation_token token_;
};

template <typename SIG, typename F> // F models void ()
cancelable_function<F, SIG> make_cancelable(F f, cancellation_token token) {
return cancelable_function<F, SIG>(f, token);
}

/**************************************************************************************************/

} // namespace adobe

/**************************************************************************************************/
Expand Down

0 comments on commit feb4b46

Please sign in to comment.