Skip to content

Commit 4c34b90

Browse files
committed
feat: application
1 parent 91c2aef commit 4c34b90

5 files changed

Lines changed: 242 additions & 0 deletions

File tree

include/boost/rts.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#ifndef BOOST_RTS_HPP
1111
#define BOOST_RTS_HPP
1212

13+
#include <boost/rts/application.hpp>
1314
#include <boost/rts/polystore.hpp>
1415

1516
#endif

include/boost/rts/application.hpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//
2+
// Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot com)
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
// Official repository: https://github.com/cppalliance/beast2
8+
//
9+
10+
#ifndef BOOST_RTS_APPLICATION_HPP
11+
#define BOOST_RTS_APPLICATION_HPP
12+
13+
#include <boost/rts/detail/config.hpp>
14+
#include <boost/rts/polystore.hpp>
15+
#include <memory>
16+
#include <type_traits>
17+
18+
namespace boost {
19+
namespace rts {
20+
21+
/** A collection of type-erased parts and process state
22+
23+
An object of this type holds a collection of type-erased parts,
24+
where each part undergoes two-phase initialization. First the part is
25+
constructed by calling @ref emplace. The @ref start function invokes
26+
`start()` on each part. When @ref stop is called, each part has its
27+
`stop()` member invoked. And when the application object is destroyed,
28+
all the parts are destroyed in reverse order of construction.
29+
*/
30+
class BOOST_SYMBOL_VISIBLE
31+
application : public rts::polystore
32+
{
33+
public:
34+
application(application const&) = delete;
35+
application& operator=(application const&) = delete;
36+
37+
/** Destructor
38+
39+
All stored objects will be destroyed in the reverse order of creation.
40+
*/
41+
BOOST_RTS_DECL
42+
~application();
43+
44+
/** Constructor
45+
*/
46+
BOOST_RTS_DECL
47+
application();
48+
49+
/** Invoke `start` on each part in creation order
50+
Each call is performed synchronously; this function blocks until each
51+
part returns. Only one invocation of `start` is permitted.
52+
*/
53+
BOOST_RTS_DECL
54+
void start();
55+
56+
/** Invoke `stop` on each part in reverse creation order
57+
This function is idempotent and returns immediately.
58+
@par Thread Safety
59+
May be called concurrently.
60+
*/
61+
BOOST_RTS_DECL
62+
void stop();
63+
64+
/** Wait until the application is stopped
65+
*/
66+
BOOST_RTS_DECL
67+
void join();
68+
69+
private:
70+
enum state : char;
71+
struct impl;
72+
impl* impl_;
73+
};
74+
75+
} // rts
76+
} // boost
77+
78+
#endif

src/application.cpp

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
//
2+
// Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot com)
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
// Official repository: https://github.com/cppalliance/beast2
8+
//
9+
10+
#include <boost/rts/application.hpp>
11+
#include <boost/rts/detail/except.hpp>
12+
#include <mutex>
13+
#include <vector>
14+
15+
namespace boost {
16+
namespace rts {
17+
18+
enum application::state : char
19+
{
20+
none,
21+
starting,
22+
running,
23+
stopping,
24+
stopped
25+
};
26+
27+
struct application::impl
28+
{
29+
std::mutex m;
30+
state st = state::none;
31+
};
32+
33+
application::
34+
~application()
35+
{
36+
{
37+
std::lock_guard<std::mutex> lock(impl_->m);
38+
if( impl_->st != state::stopped &&
39+
impl_->st != state::none)
40+
{
41+
// stop() hasn't returned yet
42+
detail::throw_invalid_argument();
43+
}
44+
}
45+
delete impl_;
46+
}
47+
48+
application::
49+
application()
50+
: impl_(new impl)
51+
{
52+
}
53+
54+
void
55+
application::
56+
start()
57+
{
58+
{
59+
std::lock_guard<std::mutex> lock(impl_->m);
60+
if(impl_->st != state::none)
61+
{
62+
// can't call twice
63+
detail::throw_invalid_argument();
64+
}
65+
impl_->st = state::starting;
66+
}
67+
auto v = get_elements();
68+
for(std::size_t i = 0; i < v.size(); ++i)
69+
{
70+
try
71+
{
72+
v[i].start();
73+
}
74+
catch(std::exception const&)
75+
{
76+
{
77+
std::lock_guard<std::mutex> lock(impl_->m);
78+
impl_->st = state::stopping;
79+
}
80+
do
81+
{
82+
v[i].stop();
83+
}
84+
while(i-- != 0);
85+
{
86+
std::lock_guard<std::mutex> lock(impl_->m);
87+
impl_->st = state::stopped;
88+
}
89+
throw;
90+
}
91+
}
92+
{
93+
std::lock_guard<std::mutex> lock(impl_->m);
94+
impl_->st = state::running;
95+
}
96+
}
97+
98+
void
99+
application::
100+
stop()
101+
{
102+
{
103+
std::lock_guard<std::mutex> lock(impl_->m);
104+
if(impl_->st != state::running)
105+
detail::throw_invalid_argument();
106+
impl_->st = state::stopping;
107+
}
108+
109+
auto v = get_elements();
110+
for(std::size_t i = v.size(); i--;)
111+
v[i].stop();
112+
113+
{
114+
std::lock_guard<std::mutex> lock(impl_->m);
115+
impl_->st = state::stopped;
116+
}
117+
}
118+
119+
} // rts
120+
} // boost

test/unit/application.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
// Official repository: https://github.com/cppalliance/beast2
8+
//
9+
10+
// Test that header file is self-contained.
11+
#include <boost/rts/application.hpp>
12+
13+
#include "test_suite.hpp"
14+
15+
namespace boost {
16+
namespace rts {
17+
18+
struct application_test
19+
{
20+
void
21+
run()
22+
{
23+
application app;
24+
}
25+
};
26+
27+
TEST_SUITE(
28+
application_test,
29+
"boost.rts.application");
30+
31+
} // rts
32+
} // boost

test/unit/rts.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//
2+
// Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
// Official repository: https://github.com/cppalliance/rts
8+
//
9+
10+
// Test that header file is self-contained.
11+
#include <boost/rts.hpp>

0 commit comments

Comments
 (0)