#include <future>
#include <chrono>
+#include <boost/asio/append.hpp>
+#include <boost/asio/async_result.hpp>
#include "boost/container/static_vector.hpp"
// -----------------------------------------------------------------------------
template <typename CompletionToken>
auto QccCrypto::async_get_instance(CompletionToken&& token) {
- using boost::asio::async_completion;
using Signature = void(int);
- async_completion<CompletionToken, Signature> init(token);
-
- auto ex = boost::asio::get_associated_executor(init.completion_handler);
-
- boost::asio::post(my_pool, [this, ex, handler = std::move(init.completion_handler)]()mutable{
- auto handler1 = std::move(handler);
- if (!open_instances.empty()) {
- int avail_inst = open_instances.front();
- open_instances.pop_front();
- boost::asio::post(ex, std::bind(handler1, avail_inst));
- } else if (!instance_completions.full()) {
- // keep a few objects to wait QAT instance to make sure qat full utilization as much as possible,
- // that is, QAT don't need to wait for new objects to ensure
- // that QAT will not be in a free state as much as possible
- instance_completions.push_back([ex, handler2 = std::move(handler1)](int inst)mutable{
- boost::asio::post(ex, std::bind(handler2, inst));
- });
- } else {
- boost::asio::post(ex, std::bind(handler1, NON_INSTANCE));
- }
- });
- return init.result.get();
+ return boost::asio::async_initiate<CompletionToken, Signature>(
+ [this] (auto handler) {
+ boost::asio::post(my_pool, [this, handler = std::move(handler)]()mutable{
+ if (!open_instances.empty()) {
+ int avail_inst = open_instances.front();
+ open_instances.pop_front();
+ boost::asio::post(boost::asio::append(std::move(handler), avail_inst));
+ } else if (!instance_completions.full()) {
+ // keep a few objects to wait QAT instance to make sure qat full utilization as much as possible,
+ // that is, QAT don't need to wait for new objects to ensure
+ // that QAT will not be in a free state as much as possible
+ instance_completions.push_back(std::move(handler));
+ } else {
+ boost::asio::post(boost::asio::append(std::move(handler), NON_INSTANCE));
+ }
+ });
+ }, token);
}
void QccCrypto::QccFreeInstance(int entry) {
boost::asio::post(my_pool, [this, entry]()mutable{
if (!instance_completions.empty()) {
- instance_completions.front()(entry);
+ boost::asio::dispatch(boost::asio::append(
+ std::move(instance_completions.front()), entry));
instance_completions.pop_front();
} else {
open_instances.push_back(entry);
}
template <typename CompletionToken>
-auto QatCrypto::async_perform_op(int avail_inst, std::span<CpaCySymDpOpData*> pOpDataVec, CompletionToken&& token) {
- CpaStatus status = CPA_STATUS_SUCCESS;
- using boost::asio::async_completion;
+auto QatCrypto::async_perform_op(std::span<CpaCySymDpOpData*> pOpDataVec, CompletionToken&& token) {
using Signature = void(CpaStatus);
- async_completion<CompletionToken, Signature> init(token);
- auto ex = boost::asio::get_associated_executor(init.completion_handler);
- completion_handler = [ex, handler = init.completion_handler](CpaStatus stat) {
- boost::asio::post(ex, std::bind(handler, stat));
- };
+ return boost::asio::async_initiate<CompletionToken, Signature>(
+ [this] (auto handler, std::span<CpaCySymDpOpData*> pOpDataVec) {
+ completion_handler = std::move(handler);
+
+ count = pOpDataVec.size();
+ poll_inst_cv.notify_one();
+ CpaStatus status = cpaCySymDpEnqueueOpBatch(pOpDataVec.size(), pOpDataVec.data(), CPA_TRUE);
- count = pOpDataVec.size();
- poll_inst_cv.notify_one();
- status = cpaCySymDpEnqueueOpBatch(pOpDataVec.size(), pOpDataVec.data(), CPA_TRUE);
+ if (status != CPA_STATUS_SUCCESS) {
+ boost::asio::post(bind_executor(ex,
+ boost::asio::append(std::move(completion_handler), status)));
+ }
+ }, token, pOpDataVec);
+}
- if (status != CPA_STATUS_SUCCESS) {
- completion_handler(status);
+void QatCrypto::complete() {
+ if (--count == 0) {
+ boost::asio::post(bind_executor(ex,
+ boost::asio::append(std::move(completion_handler), CPA_STATUS_SUCCESS)));
}
- return init.result.get();
+ return;
}
bool QccCrypto::symPerformOp(int avail_inst,
Cpa32U iv_index = 0;
size_t perform_retry_num = 0;
for (Cpa32U off = 0; off < size; off += one_batch_size) {
- QatCrypto helper;
+ QatCrypto helper{my_pool.get_executor()};
boost::container::static_vector<CpaCySymDpOpData*, MAX_NUM_SYM_REQ_BATCH> pOpDataVec;
for (Cpa32U offset = off, i = 0; offset < size && i < MAX_NUM_SYM_REQ_BATCH; offset += chunk_size, i++) {
CpaCySymDpOpData *pOpData = qcc_op_mem[avail_inst].sym_op_data[i];
poll_retry_num = RETRY_MAX_NUM;
if (y) {
spawn::yield_context yield = y.get_yield_context();
- status = helper.async_perform_op(avail_inst, std::span<CpaCySymDpOpData*>(pOpDataVec), yield);
+ status = helper.async_perform_op(std::span<CpaCySymDpOpData*>(pOpDataVec), yield);
} else {
- auto result = helper.async_perform_op(avail_inst, std::span<CpaCySymDpOpData*>(pOpDataVec), boost::asio::use_future);
+ auto result = helper.async_perform_op(std::span<CpaCySymDpOpData*>(pOpDataVec), boost::asio::use_future);
status = result.get();
}
if (status == CPA_STATUS_RETRY) {
#include <functional>
#include <span>
#include <boost/circular_buffer.hpp>
+#include <boost/asio/any_completion_handler.hpp>
#include <boost/asio/thread_pool.hpp>
#include <boost/asio/use_future.hpp>
extern "C" {
boost::asio::thread_pool my_pool{1};
- boost::circular_buffer<std::function<void(int)>> instance_completions;
+ boost::circular_buffer<boost::asio::any_completion_handler<void(int)>> instance_completions;
template <typename CompletionToken>
auto async_get_instance(CompletionToken&& token);
class QatCrypto {
private:
- std::function<void(CpaStatus stat)> completion_handler;
+ boost::asio::any_io_executor ex;
+ boost::asio::any_completion_handler<void(CpaStatus stat)> completion_handler;
std::atomic<std::size_t> count;
public:
- void complete() {
- if (--count == 0) {
- completion_handler(CPA_STATUS_SUCCESS);
- }
- return ;
- }
+ void complete();
- QatCrypto () : count(0) {}
+ QatCrypto (boost::asio::any_io_executor ex) : ex(ex), count(0) {}
QatCrypto (const QatCrypto &qat) = delete;
QatCrypto (QatCrypto &&qat) = delete;
void operator=(const QatCrypto &qat) = delete;
void operator=(QatCrypto &&qat) = delete;
template <typename CompletionToken>
- auto async_perform_op(int avail_inst, std::span<CpaCySymDpOpData*> pOpDataVec, CompletionToken&& token);
+ auto async_perform_op(std::span<CpaCySymDpOpData*> pOpDataVec, CompletionToken&& token);
};
#endif //QCCCRYPTO_H