2012-10-14 01:54:56 +02:00
|
|
|
/** ==========================================================================
|
|
|
|
* 2012 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
|
|
|
|
* with no warranties. This code is yours to share, use and modify with no
|
|
|
|
* strings attached and no restrictions or obligations.
|
2020-12-16 14:51:26 +01:00
|
|
|
*
|
2014-07-03 23:42:19 +02:00
|
|
|
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
2012-10-14 01:54:56 +02:00
|
|
|
* ============================================================================*/
|
|
|
|
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
|
|
#include <chrono>
|
|
|
|
#include <exception>
|
|
|
|
#include <functional>
|
2023-12-01 00:17:45 +01:00
|
|
|
#include <future>
|
2012-10-14 01:54:56 +02:00
|
|
|
#include <memory>
|
2023-12-01 00:17:45 +01:00
|
|
|
#include <string>
|
|
|
|
#include <thread>
|
2015-07-16 09:55:23 +02:00
|
|
|
#include "g3log/future.hpp"
|
2023-12-01 00:17:45 +01:00
|
|
|
#include "g3log/time.hpp"
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
std::future<std::string> sillyFutureReturn() {
|
|
|
|
std::packaged_task<std::string()> task([]() { return std::string("Hello Future"); }); // wrap the function
|
|
|
|
std::future<std::string> result = task.get_future(); // get a future
|
|
|
|
std::thread(std::move(task)).detach(); // launch on a thread
|
|
|
|
std::cout << "Waiting...";
|
|
|
|
result.wait();
|
|
|
|
return result; // already wasted
|
2012-10-14 01:54:56 +02:00
|
|
|
}
|
2016-03-18 17:50:59 +01:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
TEST(Configuration, FutureSilly) {
|
|
|
|
std::string hello = sillyFutureReturn().get();
|
|
|
|
ASSERT_STREQ(hello.c_str(), "Hello Future");
|
2012-10-14 01:54:56 +02:00
|
|
|
}
|
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
struct MsgType {
|
|
|
|
std::string msg_;
|
|
|
|
MsgType(std::string m) :
|
|
|
|
msg_(m){};
|
|
|
|
std::string msg() { return msg_; }
|
2012-10-14 01:54:56 +02:00
|
|
|
};
|
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
TEST(TestOf_CopyableCall, Expecting_SmoothSailing) {
|
|
|
|
using namespace kjellkod;
|
|
|
|
const std::string str("Hello from struct");
|
|
|
|
MsgType type(str);
|
|
|
|
std::unique_ptr<Active> bgWorker(Active::createActive());
|
|
|
|
std::future<std::string> fstring =
|
|
|
|
g3::spawn_task(std::bind(&MsgType::msg, type), bgWorker.get());
|
|
|
|
ASSERT_STREQ(str.c_str(), fstring.get().c_str());
|
2012-10-14 01:54:56 +02:00
|
|
|
}
|
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
TEST(TestOf_CopyableLambdaCall, Expecting_AllFine) {
|
|
|
|
using namespace kjellkod;
|
|
|
|
std::unique_ptr<Active> bgWorker(Active::createActive());
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
// lambda task
|
|
|
|
const std::string str_standalone("Hello from standalone");
|
|
|
|
auto msg_lambda = [=]() {
|
|
|
|
return (str_standalone + str_standalone);
|
|
|
|
};
|
|
|
|
std::string expected(str_standalone + str_standalone);
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
auto fstring_standalone = g3::spawn_task(msg_lambda, bgWorker.get());
|
|
|
|
ASSERT_STREQ(expected.c_str(), fstring_standalone.get().c_str());
|
2012-10-14 01:54:56 +02:00
|
|
|
}
|
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
template <typename F>
|
|
|
|
std::future<std::invoke_result_t<F>> ObsoleteSpawnTask(F f) {
|
|
|
|
typedef std::invoke_result_t<F> result_type;
|
|
|
|
typedef std::packaged_task<result_type()> task_type;
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
task_type task(std::move(f));
|
|
|
|
std::future<result_type> result = task.get_future();
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
std::vector<std::function<void()>> vec;
|
|
|
|
vec.push_back(g3::MoveOnCopy<task_type>(std::move(task)));
|
|
|
|
std::thread(std::move(vec.back())).detach();
|
|
|
|
result.wait();
|
|
|
|
return std::move(result);
|
2012-10-14 01:54:56 +02:00
|
|
|
}
|
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
TEST(TestOf_ObsoleteSpawnTaskWithStringReturn, Expecting_FutureString) {
|
|
|
|
std::string str("Hello");
|
|
|
|
std::string expected(str + str);
|
|
|
|
auto msg_lambda = [=]() {
|
|
|
|
return (str + str);
|
|
|
|
};
|
|
|
|
auto future_string = ObsoleteSpawnTask(msg_lambda);
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
ASSERT_STREQ(expected.c_str(), future_string.get().c_str());
|
2012-10-14 01:54:56 +02:00
|
|
|
}
|
|
|
|
// gcc thread example below
|
|
|
|
// tests code below copied from mail-list conversion between
|
|
|
|
// Lars Gullik Bjønnes and Jonathan Wakely
|
|
|
|
// http://gcc.gnu.org/ml/gcc-help/2011-11/msg00052.html
|
|
|
|
|
|
|
|
// --------------------------------------------------------------
|
2023-12-01 00:17:45 +01:00
|
|
|
namespace WORKING {
|
|
|
|
using namespace g3;
|
2012-10-14 01:54:56 +02:00
|
|
|
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
|
|
#include <future>
|
2023-12-01 00:17:45 +01:00
|
|
|
#include <iostream>
|
2012-10-14 01:54:56 +02:00
|
|
|
#include <thread>
|
|
|
|
#include <vector>
|
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
std::vector<std::function<void()>> vec;
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
template <typename F>
|
|
|
|
std::future<std::invoke_result_t<F>> spawn_task(F f) {
|
|
|
|
typedef std::invoke_result_t<F> result_type;
|
|
|
|
typedef std::packaged_task<result_type()> task_type;
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
task_type task(std::move(f));
|
|
|
|
std::future<result_type> res = task.get_future();
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
vec.push_back(
|
|
|
|
MoveOnCopy<task_type>(
|
|
|
|
std::move(task)));
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
std::thread([]() {
|
|
|
|
auto task = std::move(vec.back());
|
|
|
|
vec.pop_back();
|
|
|
|
task();
|
|
|
|
}).detach();
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
return std::move(res);
|
|
|
|
}
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
double get_res() {
|
|
|
|
return 42.2;
|
|
|
|
}
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
std::string msg3() {
|
|
|
|
return "msg3";
|
|
|
|
}
|
|
|
|
} // namespace WORKING
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
TEST(Yalla, Testar) {
|
|
|
|
using namespace WORKING;
|
|
|
|
auto f = spawn_task(get_res);
|
|
|
|
ASSERT_EQ(42.2, f.get());
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
auto f2 = spawn_task(msg3);
|
|
|
|
ASSERT_EQ("msg3", f2.get());
|
2012-10-14 01:54:56 +02:00
|
|
|
|
2023-12-01 00:17:45 +01:00
|
|
|
ASSERT_TRUE(true);
|
2012-10-14 01:54:56 +02:00
|
|
|
}
|