-
Notifications
You must be signed in to change notification settings - Fork 104
/
sample_readme_6.cpp
155 lines (129 loc) · 4.99 KB
/
sample_readme_6.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
* sample_readme_6.cpp
*
* Created on: 2020-05-20
* Author: owent
*
* Released under the MIT license
*/
#include <assert.h>
#include <iostream>
#include <list>
// include manager header file
#include <libcopp/future/future.h>
#include <libcopp/future/context.h>
struct example_result_message_t {
int return_code;
int response_code;
};
struct example_poller;
typedef copp::future::result_t<
example_result_message_t, // polled data if success
int // error code if failed
> example_result_t;
typedef copp::future::future_t<example_result_t> example_future_t;
typedef copp::future::context_t<example_poller> example_context_t;
std::list<example_context_t*> g_executor;
struct example_poller {
example_result_t::storage_type* result;
std::list<example_context_t*>::iterator iter;
example_poller(): result(NULL) {
iter = g_executor.end();
}
~example_poller() {
// cleanup and remove from executor
if (iter != g_executor.end()) {
g_executor.erase(iter);
}
}
void operator()(example_future_t& future, example_context_t &ctx) {
if (NULL != result) {
future.poll_data() = *result;
result = NULL;
// remove from executor
if (iter != g_executor.end()) {
g_executor.erase(iter);
iter = g_executor.end();
}
} else {
// add to executor
if (iter == g_executor.end()) {
iter = g_executor.insert(g_executor.end(), &ctx);
}
}
}
};
void run_with_custom_context () {
example_future_t future;
example_context_t context;
assert(future.is_ready() == false);
// poll context for the first time and setup waker
// future should only poll one context
future.poll(context);
while (!g_executor.empty()) {
example_result_message_t msg;
// set a result message
msg.return_code = 0;
msg.response_code = 200;
// if both success type and error type is a small trivial type, storage_type will be result_t with union of success type and error type
// else storage_type will be std::unique_ptr<result_t>
// result_t::make_success(...) and result_t::make_error(...) will make sure to use the correct storage type
example_result_t::storage_type result_storage = example_result_t::make_success(msg);
(*g_executor.begin())->get_private_data().result = &result_storage;
// just call context_t::wake to wakeup and poll again
(*g_executor.begin())->wake();
}
// Then future is ready
assert(future.is_ready() == true);
example_result_t* result = future.data();
assert(result != NULL);
assert(result->is_success());
assert(200 == result->get_success()->response_code);
assert(false == result->is_error());
assert(NULL == result->get_error());
std::cout<< "Got future success response code: "<< result->get_success()->response_code<< std::endl;
}
static void custom_poller_function(copp::future::context_t<void> &, copp::future::context_t<void>::poll_event_data_t evt_data) {
if (NULL == evt_data.private_data) {
return;
}
example_future_t* future = reinterpret_cast<example_future_t*>(evt_data.future_ptr);
example_result_message_t* msg = reinterpret_cast<example_result_message_t*>(evt_data.private_data);
// if both success type and error type is a small trivial type, storage_type will be result_t with union of success type and error type
// else storage_type will be std::unique_ptr<result_t>
// result_t::make_success(...) and result_t::make_error(...) will make sure to use the correct storage type
future->poll_data() = example_result_t::make_success(*msg);
}
void run_with_void_context () {
example_future_t future;
copp::future::context_t<void> context(copp::future::context_t<void>::construct(custom_poller_function));
// upper code equal to:
// copp::future::context_t<void> context;
// context.set_poll_fn(custom_poller_function);
assert(future.is_ready() == false);
// poll context for the first time and setup waker
// future should only poll one context
future.poll(context);
while (!future.is_ready()) {
example_result_message_t msg;
// set a result message
msg.return_code = 0;
msg.response_code = 200;
context.set_private_data(reinterpret_cast<void*>(&msg));
context.wake();
}
// Then future is ready
assert(future.is_ready() == true);
example_result_t* result = future.data();
assert(result != NULL);
assert(result->is_success());
assert(200 == result->get_success()->response_code);
assert(false == result->is_error());
assert(NULL == result->get_error());
std::cout<< "Got future success response code(context_t<void>): "<< result->get_success()->response_code<< std::endl;
}
int main() {
run_with_custom_context();
run_with_void_context();
return 0;
}