-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add capability to process generic callbacks in progress thread (#65)
Implement and use generic callbacks to create endpoints, close endpoints and listeners, and probe tags. By doing this we ensure those don't need to take the UCS spinlock or progress the worker during the application thread, which can be sources of deadlocks. Authors: - Peter Andreas Entschev (https://github.com/pentschev) - Lawrence Mitchell (https://github.com/wence-) Approvers: - Lawrence Mitchell (https://github.com/wence-) URL: #65
- Loading branch information
Showing
17 changed files
with
485 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/** | ||
* SPDX-FileCopyrightText: Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
#include <condition_variable> | ||
#include <functional> | ||
#include <memory> | ||
#include <mutex> | ||
#include <utility> | ||
|
||
namespace ucxx { | ||
|
||
namespace utils { | ||
|
||
template <typename Flag> | ||
class CallbackNotifier { | ||
private: | ||
Flag _flag{}; //< flag storing state | ||
std::mutex _mutex{}; //< lock to guard accesses | ||
std::condition_variable _conditionVariable{}; //< notification condition var | ||
|
||
public: | ||
/** | ||
* @brief Construct a thread-safe notification object with given initial value. | ||
* | ||
* Construct a thread-safe notification object with a given initial value which may be | ||
* later set via `store()` in one thread and block other threads running `wait()` while | ||
* the new value is not set. | ||
* | ||
* @param[in] init The initial flag value | ||
*/ | ||
explicit CallbackNotifier(Flag flag) : _flag{flag} {} | ||
|
||
~CallbackNotifier() {} | ||
|
||
CallbackNotifier(const CallbackNotifier&) = delete; | ||
CallbackNotifier& operator=(CallbackNotifier const&) = delete; | ||
CallbackNotifier(CallbackNotifier&& o) = delete; | ||
CallbackNotifier& operator=(CallbackNotifier&& o) = delete; | ||
|
||
/** | ||
* @brief Store a new flag value and notify waiting threads. | ||
* | ||
* Store a new flag value and notify others threads blocked by a call to `wait()`. | ||
* See also `std::condition_variable::notify_all`. | ||
* | ||
* @param[in] flag The new flag value. | ||
*/ | ||
void store(Flag flag) | ||
{ | ||
{ | ||
std::lock_guard lock(_mutex); | ||
_flag = flag; | ||
} | ||
_conditionVariable.notify_all(); | ||
} | ||
|
||
/** | ||
* @brief Wait while predicate is not true for the flag value to change. | ||
* | ||
* Wait while predicate is not true which should be satisfied by a change in the flag's | ||
* value by a `store()` call on a different thread. | ||
* | ||
* @param[in] compare Function of type `T -> bool` called with the flag value. This | ||
* function loops until the predicate is satisfied. See also | ||
* `std::condition_variable::wait`. | ||
* @param[out] The new flag value. | ||
*/ | ||
template <typename Compare> | ||
Flag wait(Compare compare) | ||
{ | ||
std::unique_lock lock(_mutex); | ||
_conditionVariable.wait(lock, [this, &compare]() { return compare(_flag); }); | ||
return std::move(_flag); | ||
} | ||
}; | ||
|
||
} // namespace utils | ||
// | ||
} // namespace ucxx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.