Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit174f8a5

Browse files
committed
ensure mutual exclusion of aoBindToThread and aoExclusive
1 parent538bfc6 commit174f8a5

File tree

4 files changed

+60
-56
lines changed

4 files changed

+60
-56
lines changed

‎lib/acto.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,12 @@ void startup() {
147147

148148
namespacecore {
149149

150-
object_t::object_t(actor*const impl_)
151-
: impl(impl_)
152-
, binded(false)
150+
object_t::object_t(constuint32_t options, std::unique_ptr<actor> body)
151+
: impl(body.release())
152+
, references(1)
153+
, binded(bool(options & acto::aoBindToThread))
154+
, exclusive(bool(options & acto::aoExclusive))
153155
, deleting(false)
154-
, exclusive(false)
155156
, scheduled(false)
156157
, unimpl(false) {
157158
}

‎lib/acto.h

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include<atomic>
88
#include<functional>
9+
#include<memory>
910
#include<mutex>
1011
#include<thread>
1112
#include<typeindex>
@@ -17,12 +18,12 @@ namespace acto {
1718
classactor;
1819

1920
/// Use dedicated thread for an actor.
20-
staticconstexprint aoExclusive =0x01;
21+
staticconstexpruint32_t aoExclusive =0x01;
2122

2223
/// Привязать актера к текущему системному потоку.
2324
/// Не имеет эффекта, если используется в контексте потока,
2425
/// созданного самой библиотекой.
25-
staticconstexprint aoBindToThread =0x02;
26+
staticconstexpruint32_t aoBindToThread =0x02;
2627

2728
namespacecore {
2829

@@ -31,7 +32,7 @@ class worker_t;
3132
structmsg_t;
3233

3334
/**
34-
*Объект
35+
*Core object.
3536
*/
3637
structobject_t :publicgenerics::intrusive_t<object_t> {
3738
structwaiter_t :publicgenerics::intrusive_t<waiter_t> {
@@ -45,7 +46,7 @@ struct object_t : public generics::intrusive_t<object_t> {
4546
std::recursive_mutex cs;
4647

4748
/// Pointer to the object inherited from the actor class (aka actor body).
48-
actor* impl{nullptr};
49+
actor* impl;
4950
/// Dedicated thread for the object.
5051
worker_t* thread{nullptr};
5152
// Список сигналов для потоков, ожидающих уничтожения объекта.
@@ -56,14 +57,14 @@ struct object_t : public generics::intrusive_t<object_t> {
5657
// Count of references to the object.
5758
std::atomic<unsignedlong> references{0};
5859
/// State flags.
59-
uint32_t binded :1;
60+
constuint32_t binded :1;
61+
constuint32_t exclusive :1;
6062
uint32_t deleting :1;
61-
uint32_t exclusive :1;
6263
uint32_t scheduled :1;
6364
uint32_t unimpl :1;
6465

6566
public:
66-
object_t(actor*constimpl_);
67+
object_t(constuint32_t options, std::unique_ptr<actor> body);
6768

6869
/// Pushes a message into the mailbox.
6970
voidenqueue(std::unique_ptr<msg_t> msg)noexcept;
@@ -427,25 +428,20 @@ ACTO_API void startup();
427428

428429
namespacecore {
429430

430-
object_t*make_instance(actor_ref context,constint options, actor* body);
431+
object_t*make_instance(
432+
actor_ref context,constuint32_t options, std::unique_ptr<actor> body);
431433

432434
}// namespace core
433435

434436
namespacedetail {
435437

436438
template<typename Impl>
437439
inline core::object_t*make_instance(
438-
actor_ref context,constint options, Impl* impl) {
440+
actor_ref context,constuint32_t options,std::unique_ptr<Impl> impl) {
439441
static_assert(std::is_base_of<::acto::actor, Impl>::value,
440442
"implementation should be derived from the acto::actor class");
441443

442-
returncore::make_instance(std::move(context), options, impl);
443-
}
444-
445-
template<typename Impl>
446-
inline core::object_t*make_instance(
447-
actor_ref context,constint options, std::unique_ptr<Impl> impl) {
448-
returnmake_instance(std::move(context), options, impl.release());
444+
returncore::make_instance(std::move(context), options,std::move(impl));
449445
}
450446

451447
}// namespace detail
@@ -465,14 +461,14 @@ inline actor_ref spawn(actor_ref context) {
465461
}
466462

467463
template<typename T>
468-
inline actor_refspawn(constint options) {
464+
inline actor_refspawn(constuint32_t options) {
469465
returnactor_ref(
470466
detail::make_instance<T>(actor_ref(), options, std::make_unique<T>()),
471467
false);
472468
}
473469

474470
template<typename T>
475-
inline actor_refspawn(actor_ref context,constint options) {
471+
inline actor_refspawn(actor_ref context,constuint32_t options) {
476472
returnactor_ref(detail::make_instance<T>(
477473
std::move(context), options, std::make_unique<T>()),
478474
false);

‎lib/runtime.cpp

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -56,37 +56,35 @@ unsigned long runtime_t::acquire(object_t* const obj) const noexcept {
5656
return ++obj->references;
5757
}
5858

59-
object_t*runtime_t::create_actor(actor*const body,constint options) {
59+
object_t*runtime_t::create_actor(
60+
std::unique_ptr<actor> body,constuint32_t options) {
6061
assert(body);
62+
assert(!((options & aoBindToThread) && (options & aoExclusive)));
6163

62-
object_t*const result =newcore::object_t(body);
63-
64-
result->references =1;
65-
// Зарегистрировать объект в системе
66-
if (options & acto::aoBindToThread) {
64+
object_t*const result =newcore::object_t(options,std::move(body));
65+
// Bind actor to the current thread.
66+
if (result->binded) {
6767
result->references +=1;
68-
result->binded =true;
69-
7068
thread_context->actors.insert(result);
7169
}else {
72-
std::lock_guard<std::mutex>g(m_cs);
73-
74-
result->exclusive = options & acto::aoExclusive;
70+
{
71+
std::lock_guard<std::mutex>g(m_cs);
7572

76-
m_actors.insert(result);
73+
m_actors.insert(result);
7774

78-
m_clean.reset();
79-
}
80-
// Create dedicated thread for the actor if necessary.
81-
if (options & acto::aoExclusive) {
82-
worker_t*const worker =this->create_worker();
75+
m_clean.reset();
76+
}
77+
// Create dedicated thread for the actor if necessary.
78+
if (result->exclusive) {
79+
worker_t*const worker =create_worker();
8380

84-
result->scheduled =true;
85-
result->thread = worker;
81+
result->scheduled =true;
82+
result->thread = worker;
8683

87-
++m_workers.reserved;
84+
++m_workers.reserved;
8885

89-
worker->assign(result,std::chrono::steady_clock::duration());
86+
worker->assign(result,std::chrono::steady_clock::duration());
87+
}
9088
}
9189

9290
return result;
@@ -278,7 +276,7 @@ bool runtime_t::send_on_behalf(
278276
}
279277

280278
voidruntime_t::shutdown() {
281-
this->destroy_thread_binding();
279+
destroy_thread_binding();
282280

283281
// 1. Инициировать процедуру удаления для всех оставшихся объектов
284282
{
@@ -302,6 +300,8 @@ void runtime_t::startup() {
302300

303301
voidruntime_t::process_binded_actors(
304302
actors_set& actors,constbool need_delete) {
303+
// TODO: - switch between active actors to balance message processing.
304+
// - detect message loop.
305305
for (auto ai = actors.cbegin(); ai != actors.cend(); ++ai) {
306306
while (auto msg = (*ai)->select_message()) {
307307
handle_message(std::move(msg));
@@ -321,17 +321,15 @@ void runtime_t::process_binded_actors(
321321
}
322322

323323
object_t*runtime_t::make_instance(
324-
actor_ref context,constint options, actor* body) {
324+
actor_ref context,constuint32_t options,std::unique_ptr<actor> body) {
325325
assert(body);
326-
//Создать объект ядра (счетчик ссылок увеличивается автоматически)
327-
core::object_t*const result =create_actor(body, options);
326+
//Create core object.
327+
core::object_t*const result =create_actor(std::move(body), options);
328328

329329
if (result) {
330-
body->context_ =std::move(context);
331-
body->self_ =actor_ref(result,true);
332-
body->bootstrap();
333-
}else {
334-
delete body;
330+
result->impl->context_ =std::move(context);
331+
result->impl->self_ =actor_ref(result,true);
332+
result->impl->bootstrap();
335333
}
336334

337335
return result;
@@ -440,9 +438,10 @@ void runtime_t::execute() {
440438
}
441439
}
442440

443-
object_t*make_instance(actor_ref context,constint options, actor* body) {
441+
object_t*make_instance(
442+
actor_ref context,constuint32_t options, std::unique_ptr<actor> body) {
444443
returnruntime_t::instance()->make_instance(
445-
std::move(context), options, body);
444+
std::move(context), options,std::move(body));
446445
}
447446

448447
}// namespace core

‎lib/runtime.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include"worker.h"
55

66
#include<atomic>
7+
#include<memory>
78
#include<thread>
89
#include<unordered_set>
910

@@ -29,7 +30,7 @@ class runtime_t : public worker_t::callbacks {
2930
/// Захватить ссылку на объект
3031
unsignedlongacquire(object_t*const obj)constnoexcept;
3132
/// Создать экземпляр объекта, связав его с соответсвтующей реализацией
32-
object_t*create_actor(actor*constbody,constint options);
33+
object_t*create_actor(std::unique_ptr<actor>body,constuint32_t options);
3334
/// Создать контекст связи с текущим системным потоком
3435
voidcreate_thread_binding();
3536
/// Уничтожить объект
@@ -60,7 +61,8 @@ class runtime_t : public worker_t::callbacks {
6061
/// Начать выполнение
6162
voidstartup();
6263

63-
object_t*make_instance(actor_ref context,constint options, actor* body);
64+
object_t*make_instance(
65+
actor_ref context,constuint32_t options, std::unique_ptr<actor> body);
6466

6567
private:
6668
voidpush_delete(object_t*const obj)override;
@@ -76,6 +78,12 @@ class runtime_t : public worker_t::callbacks {
7678

7779
worker_t*create_worker();
7880

81+
/**
82+
* @brief Processes all available messages for the given acctors.
83+
*
84+
* @param actors set of actors to process.
85+
* @param need_delete delete actors after process all messages.
86+
*/
7987
voidprocess_binded_actors(actors_set& actors,constbool need_delete);
8088

8189
private:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp