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

Commit12c59bc

Browse files
committed
get rid of recursive mutex
1 parentdc8050d commit12c59bc

File tree

4 files changed

+34
-34
lines changed

4 files changed

+34
-34
lines changed

‎lib/acto.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,7 @@ object_t::object_t(const actor_thread thread_opt, std::unique_ptr<actor> body)
134134
, binded(thread_opt == actor_thread::bind)
135135
, exclusive(thread_opt == actor_thread::exclusive)
136136
, deleting(false)
137-
, scheduled(false)
138-
, unimpl(false) {
137+
, scheduled(false) {
139138
}
140139

141140
voidobject_t::enqueue(std::unique_ptr<msg_t> msg)noexcept {

‎lib/acto.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,26 +47,24 @@ struct object_t : public generics::intrusive_t<object_t> {
4747
usingatomic_stack_t = generics::mpsc_stack_t<msg_t>;
4848
usingintusive_stack_t = generics::stack_t<msg_t>;
4949

50-
// Критическая секция для доступа к полям
51-
std::recursive_mutex cs;
52-
50+
/// State mutex.
51+
std::mutex cs;
5352
/// Pointer to the object inherited from the actor class (aka actor body).
5453
actor* impl;
5554
/// Dedicated thread for the object.
5655
worker_t* thread{nullptr};
57-
// Список сигналов для потоков, ожидающих уничтожения объекта.
58-
waiter_t* waiters{nullptr};
59-
// Очередь сообщений, поступивших данному объекту
56+
/// Queue of input messages implemented with two stacks.
6057
atomic_stack_t input_stack;
6158
intusive_stack_t local_stack;
62-
// Count of references to the object.
59+
/// Count of references to the object.
6360
std::atomic<unsignedlong> references{0};
61+
/// List of events awaiting for object deconstruction.
62+
waiter_t* waiters{nullptr};
6463
/// State flags.
6564
constuint32_t binded :1;
6665
constuint32_t exclusive :1;
6766
uint32_t deleting :1;
6867
uint32_t scheduled :1;
69-
uint32_t unimpl :1;
7068

7169
public:
7270
object_t(const actor_thread thread_opt, std::unique_ptr<actor> body);

‎lib/runtime.cpp

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -98,49 +98,55 @@ void runtime_t::deconstruct_object(object_t* const obj) {
9898
assert(obj);
9999

100100
{
101-
std::lock_guard<std::recursive_mutex>g(obj->cs);
102-
// Return from a recursive call
103-
// during deletion of the actor's body.
104-
if (obj->unimpl) {
105-
return;
106-
}
101+
std::lock_guard<std::mutex>g(obj->cs);
102+
107103
obj->deleting =true;
108104
// The object still has some messages in the mailbox.
109105
if (obj->scheduled) {
110106
return;
111-
}else {
112-
assert(!obj->has_messages());
113107
}
108+
//
114109
if (obj->impl) {
115-
if (obj->thread) {
116-
--workers_.reserved;
117-
obj->thread->wakeup();
118-
}
110+
// Take temporary reference to the object to avoid calling the decontruct
111+
// function during deleteing the object's body.
112+
obj->references++;
119113

120-
obj->unimpl =true;
121114
delete obj->impl, obj->impl =nullptr;
122-
obj->unimpl =false;
123115

124116
if (obj->waiters) {
125117
for (object_t::waiter_t* it = obj->waiters; it !=nullptr;) {
126-
// TN: Необходимо читать значение следующего указателя
127-
// заранее, так как пробуждение ждущего потока
128-
// приведет к удалению текущего узла списка
118+
// Make the event signaled will lead to destruction of the list node.
119+
// So retrieve pointer to the next node beforehand.
129120
object_t::waiter_t* next = it->next;
130121
it->event.signaled();
131122
it = next;
132123
}
133124

134125
obj->waiters =nullptr;
135126
}
127+
128+
obj->references--;
129+
}
130+
// The didicated thread will place itself into shared pool.
131+
if (obj->thread) {
132+
--workers_.reserved;
133+
obj->thread->wakeup();
134+
obj->thread =nullptr;
136135
}
137136
// Cannot delete the object if there are still some references to it.
138137
if (obj->references) {
139138
return;
140139
}
141140
}
141+
142+
constbool is_binded = obj->binded;
143+
144+
// There are no more references to the object,
145+
// so delete it.
146+
delete obj;
147+
142148
// Remove object from the global registry.
143-
if (!obj->binded) {
149+
if (!is_binded) {
144150
std::lock_guard<std::mutex>g(mutex_);
145151

146152
actors_.erase(obj);
@@ -149,9 +155,6 @@ void runtime_t::deconstruct_object(object_t* const obj) {
149155
no_actors_event_.signaled();
150156
}
151157
}
152-
// There are no more references to the object,
153-
// so delete it.
154-
delete obj;
155158
}
156159

157160
voidruntime_t::handle_message(std::unique_ptr<msg_t> msg) {
@@ -185,7 +188,7 @@ void runtime_t::join(object_t* const obj) {
185188
object_t::waiter_t node;
186189

187190
{
188-
std::lock_guard<std::recursive_mutex>g(obj->cs);
191+
std::lock_guard<std::mutex>g(obj->cs);
189192

190193
if (obj->impl) {
191194
node.event.reset();
@@ -227,7 +230,7 @@ bool runtime_t::send_on_behalf(object_t* const target,
227230
assert(target);
228231

229232
{
230-
std::lock_guard<std::recursive_mutex>g(target->cs);
233+
std::lock_guard<std::mutex>g(target->cs);
231234
// Cannot send messages to deleting object.
232235
if (target->deleting) {
233236
returnfalse;

‎lib/worker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ bool worker_t::process() {
7070

7171
// There are no messages in the object's mailbox or
7272
// the time slice was elapsed.
73-
std::lock_guard<std::recursive_mutex>g(obj->cs);
73+
std::lock_guard<std::mutex>g(obj->cs);
7474

7575
if (obj->deleting) {
7676
need_delete =true;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp