Skip to content

Commit 147eb88

Browse files
committed
readme, trivial mx stuff, about to expand
1 parent 250b8ff commit 147eb88

File tree

2 files changed

+66
-12
lines changed

2 files changed

+66
-12
lines changed

README.md

+40-8
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,55 @@
11
# kit
2-
My personal C++11 toolset
2+
Really cool C++ stuff, including modern async
33

44
Open-source under MIT License
55

66
Copyright (c) 2013 Grady O'Connell
77

88
## async
9-
- Stackful coroutines
10-
- Per-thread event loops
11-
- Coroutine-friendly YIELD(), AWAIT(), and SLEEP()
12-
- Transfer tasks between threads
13-
- Thread-safe channels
14-
- Async fstream alternative (WIP)
9+
- Coroutines w/ YIELD(), AWAIT(), and SLEEP()
10+
- Channels
11+
- Async Sockets
12+
- Event Multiplexer
13+
14+
```c++
15+
// MX thread 0, void future
16+
MX[0].coro<void>([]{
17+
// do async stuff
18+
auto foo = AWAIT(bar);
19+
20+
// async sleep yield
21+
SLEEP(chrono::milliseconds(100));
22+
});
23+
```
24+
25+
```c++
26+
// socket example
27+
MX[0].coro<void>([&]{
28+
for(;;)
29+
{
30+
auto client = make_shared<TCPSocket>(AWAIT(server->accept()));
31+
32+
// coroutine per client
33+
MX[0].coro<void>([&, client]{
34+
int client_id = client_ids++;
35+
LOGf("client %s connected", client_id);
36+
try{
37+
for(;;)
38+
AWAIT(client->send(AWAIT(client->recv())));
39+
}catch(const socket_exception& e){
40+
LOGf("client %s disconnected (%s)", client_id % e.what());
41+
}
42+
});
43+
}
44+
});
45+
46+
```
1547

1648
## reactive
1749
signals, reactive values (signal-paired vars), and lazy evaluation
1850

1951
## meta
20-
Thread-aware serializable meta-objects, property trees, and reflection
52+
JSON-compatible serializable meta-objects, property trees
2153

2254
## freq
2355
Timelines, alarms, animation/easing, waypoints/keyframes, interpolation

kit/async/mx.h

+26-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <boost/thread.hpp>
77
#include <boost/noncopyable.hpp>
88
#include <boost/coroutine/all.hpp>
9+
#include <boost/smart_ptr/make_local_shared.hpp>
910
#include <algorithm>
1011
#include <atomic>
1112
#include <deque>
@@ -82,6 +83,9 @@ typedef boost::coroutines::coroutine<void>::push_type push_coro_t;
8283
#define AWAIT_HINT(HINT, EXPR) AWAIT_HINT_MX(MUX, HINT, EXPR)
8384

8485
// coroutine async sleep()
86+
#define MX_SLEEP(TIME) Multiplexer::sleep(TIME);
87+
88+
// deprecated
8589
#define SLEEP(TIME) Multiplexer::sleep(TIME);
8690

8791
#define MX_EPSILON 0.00001
@@ -157,7 +161,7 @@ class Multiplexer:
157161
if(!m_Buffered || m_Units.size() < m_Buffered) {
158162
auto cbt = Task<T()>(std::move(cb));
159163
auto fut = cbt.get_future();
160-
auto cbc = std::make_shared<Task<T()>>(std::move(cbt));
164+
auto cbc = boost::make_local_shared<Task<T()>>(std::move(cbt));
161165
m_Units.emplace_back(cond, [cbc]() {
162166
(*cbc)();
163167
});
@@ -178,7 +182,7 @@ class Multiplexer:
178182
if(!m_Buffered || m_Units.size() < m_Buffered) {
179183
auto cbt = Task<T()>(std::move(cb));
180184
auto fut = cbt.get_future();
181-
auto cbc = std::make_shared<Task<T()>>(std::move(cbt));
185+
auto cbc = boost::make_local_shared<Task<T()>>(std::move(cbt));
182186
m_Units.emplace_back(
183187
std::function<bool()>(),
184188
std::function<void()>()
@@ -222,15 +226,15 @@ class Multiplexer:
222226
//std::shared_ptr<Channel<T>> channel(
223227
// std::function<void(std::shared_ptr<Channel<T>>)> worker
224228
//) {
225-
// auto chan = std::make_shared<Channel<>>();
229+
// auto chan = boost::make_local_shared<Channel<>>();
226230
// // ... inside lambda if(chan->closed()) remove?
227231
//}
228232

229233
// TODO: handle multi-direction channels that may block
230234

231235
template<class R, class T>
232236
std::future<R> when(std::future<T>& fut, std::function<R(std::future<T>&)> cb) {
233-
auto futc = std::make_shared<std::future<T>>(std::move(fut));
237+
auto futc = boost::make_local_shared<std::future<T>>(std::move(fut));
234238

235239
return task<void>([cb, futc]() {
236240
if(futc->wait_for(std::chrono::seconds(0)) ==
@@ -439,6 +443,7 @@ class Multiplexer:
439443
m_Circuits.emplace_back(make_tuple(
440444
kit::make_unique<Circuit>(this, i), CacheLinePadding()
441445
));
446+
//m_MultiCircuit = kit::make_unique<Circuit>(this, i);
442447
}
443448
//void join() {
444449
// for(auto& s: m_Circuits)
@@ -501,8 +506,24 @@ class Multiplexer:
501506
std::get<0>(s)->finish_nojoin();
502507
for(auto& s: m_Circuits)
503508
std::get<0>(s)->join();
509+
//for(auto& s: m_MultiCircuit)
510+
// std::get<0>(s)->finish_nojoin();
511+
//for(auto& s: m_MultiCircuit)
512+
// std::get<0>(s)->join();
504513
}
505514

515+
//template <class Time>
516+
//static bool retry(int count, Time delay, std::function<bool()> func)
517+
//{
518+
// for(int i=0; i<count || count<0; count<0 || ++i)
519+
// {
520+
// if(func())
521+
// return true;
522+
// SLEEP(delay);
523+
// }
524+
// return false;
525+
//}
526+
506527
private:
507528

508529
struct CacheLinePadding
@@ -512,6 +533,7 @@ class Multiplexer:
512533

513534
const unsigned m_Concurrency;
514535
std::vector<std::tuple<std::unique_ptr<Circuit>, CacheLinePadding>> m_Circuits;
536+
//std::unique_ptr<Circuit> m_MultiCircuit;
515537

516538
// read-write mutex might be more optimal here
517539
kit::mutex_wrap<std::map<boost::thread::id, unsigned>> m_ThreadToCircuit;

0 commit comments

Comments
 (0)