2020-08-21 14:55:03 +08:00
|
|
|
#pragma once
|
|
|
|
#include "fiber_cpp_define.hpp"
|
|
|
|
#include <thread>
|
|
|
|
#include <functional>
|
|
|
|
#include "fiber.hpp"
|
|
|
|
#include "fiber_tbox.hpp"
|
|
|
|
|
2023-06-11 18:34:41 +08:00
|
|
|
#if __cplusplus >= 201103L // Support c++11 ?
|
|
|
|
|
2020-08-21 14:55:03 +08:00
|
|
|
struct ACL_FIBER;
|
|
|
|
|
|
|
|
namespace acl {
|
|
|
|
|
2023-06-11 18:34:41 +08:00
|
|
|
class fiber_ctx {
|
2020-08-21 14:55:03 +08:00
|
|
|
public:
|
|
|
|
fiber_ctx(std::function<void()> fn) {
|
|
|
|
fn_ = std::move(fn);
|
|
|
|
}
|
|
|
|
|
|
|
|
~fiber_ctx() = default;
|
|
|
|
|
|
|
|
std::function<void()> fn_;
|
|
|
|
};
|
|
|
|
|
2021-09-14 18:34:21 +08:00
|
|
|
#define go acl::go_fiber()>
|
2023-04-04 16:35:31 +08:00
|
|
|
#define go_stack(size) acl::go_fiber(size, false)>
|
|
|
|
#define go_share(size) acl::go_fiber(size, true)>
|
2020-08-21 14:55:03 +08:00
|
|
|
|
2021-09-14 18:34:21 +08:00
|
|
|
#define go_wait_fiber acl::go_fiber()<
|
|
|
|
#define go_wait_thread acl::go_fiber()<<
|
|
|
|
#define go_wait go_wait_thread
|
2020-08-21 14:55:03 +08:00
|
|
|
|
2023-06-11 18:34:41 +08:00
|
|
|
class go_fiber {
|
2020-08-21 14:55:03 +08:00
|
|
|
public:
|
|
|
|
go_fiber(void) {}
|
2023-04-04 16:35:31 +08:00
|
|
|
go_fiber(size_t stack_size, bool on) : stack_size_(stack_size), stack_share_(on) {}
|
2020-08-21 14:55:03 +08:00
|
|
|
|
2023-06-11 18:34:41 +08:00
|
|
|
void operator > (std::function<void()> fn) {
|
2020-08-21 14:55:03 +08:00
|
|
|
fiber_ctx* ctx = new fiber_ctx(fn);
|
2023-04-04 16:35:31 +08:00
|
|
|
fiber::fiber_create(fiber_main, (void*) ctx, stack_size_, stack_share_);
|
2020-08-21 14:55:03 +08:00
|
|
|
}
|
|
|
|
|
2023-06-11 18:34:41 +08:00
|
|
|
void operator < (std::function<void()> fn) {
|
2020-08-21 14:55:03 +08:00
|
|
|
fiber_tbox<int> box;
|
|
|
|
|
|
|
|
go[&] {
|
|
|
|
fn();
|
|
|
|
box.push(NULL);
|
|
|
|
};
|
|
|
|
(void) box.pop();
|
|
|
|
}
|
|
|
|
|
2023-06-11 18:34:41 +08:00
|
|
|
void operator << (std::function<void()> fn) {
|
2020-08-21 14:55:03 +08:00
|
|
|
fiber_tbox<int> box;
|
|
|
|
|
|
|
|
std::thread thread([&]() {
|
|
|
|
fn();
|
|
|
|
box.push(NULL);
|
|
|
|
});
|
|
|
|
|
|
|
|
thread.detach();
|
|
|
|
(void) box.pop();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2023-04-04 16:35:31 +08:00
|
|
|
size_t stack_size_ = 320000;
|
|
|
|
bool stack_share_ = false;
|
2020-08-21 14:55:03 +08:00
|
|
|
|
2023-06-11 18:34:41 +08:00
|
|
|
static void fiber_main(ACL_FIBER*, void* ctx) {
|
2020-08-21 14:55:03 +08:00
|
|
|
fiber_ctx* fc = (fiber_ctx *) ctx;
|
|
|
|
std::function<void()> fn = fc->fn_;
|
|
|
|
delete fc;
|
|
|
|
|
|
|
|
fn();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace acl
|
|
|
|
|
2023-06-11 18:34:41 +08:00
|
|
|
#endif // __cplusplus >= 201103L
|
|
|
|
|
2020-08-21 14:55:03 +08:00
|
|
|
/**
|
2023-06-11 18:34:41 +08:00
|
|
|
* static void fiber1(void) {
|
2020-08-21 14:55:03 +08:00
|
|
|
* printf("fiber: %d\r\n", acl::fiber::self());
|
|
|
|
* }
|
|
|
|
*
|
2023-06-11 18:34:41 +08:00
|
|
|
* static void fiber2(acl::string& buf) {
|
2020-08-21 14:55:03 +08:00
|
|
|
* printf("in fiber: %d, buf: %s\r\n", acl::fiber::self(), buf.c_str());
|
|
|
|
* buf = "world";
|
|
|
|
* }
|
|
|
|
*
|
2023-06-11 18:34:41 +08:00
|
|
|
* static void fiber3(const acl::string& buf) {
|
2020-08-21 14:55:03 +08:00
|
|
|
* printf("in fiber: %d, buf: %s\r\n", acl::fiber::self(), buf.c_str());
|
|
|
|
* }
|
|
|
|
*
|
2023-06-11 18:34:41 +08:00
|
|
|
* static void incr(int& n) {
|
2020-08-21 14:55:03 +08:00
|
|
|
* n++;
|
|
|
|
* }
|
|
|
|
*
|
2023-06-11 18:34:41 +08:00
|
|
|
* static void waiter(void) {
|
2020-08-21 14:55:03 +08:00
|
|
|
* int n = 100;
|
|
|
|
*
|
|
|
|
* // run in thread and wait for result
|
|
|
|
* go_wait_thread[&] { incr(n); };
|
2021-09-08 00:17:57 +08:00
|
|
|
* // here: n should be 101
|
2020-08-21 14:55:03 +08:00
|
|
|
*
|
|
|
|
* n = 200;
|
|
|
|
*
|
|
|
|
* // run in fiber and wait for result
|
|
|
|
* go_wait_fiber[&] { incr(n); };
|
2021-09-08 00:17:57 +08:00
|
|
|
* // here: n should be 201
|
2020-08-21 14:55:03 +08:00
|
|
|
* }
|
|
|
|
*
|
2023-06-11 18:34:41 +08:00
|
|
|
* static test(void) {
|
2020-08-21 14:55:03 +08:00
|
|
|
* go fiber1;
|
|
|
|
*
|
|
|
|
* acl::string buf("hello");
|
|
|
|
*
|
|
|
|
* go[&] {
|
|
|
|
* fiber2(buf);
|
|
|
|
* };
|
|
|
|
*
|
|
|
|
* go[=] {
|
|
|
|
* fiber3(buf);
|
|
|
|
* };
|
|
|
|
*
|
|
|
|
* go[&] {
|
|
|
|
* fiber3(buf);
|
|
|
|
* };
|
|
|
|
* }
|
|
|
|
*/
|