@@ -117,25 +117,33 @@ void abstract_actor::del_monitor(abstract_actor* observed,
117117
118118// -- linking ------------------------------------------------------------------
119119
120- void abstract_actor::link_to (const actor_addr& other) {
121- auto lg = log::core::trace (" other = {}" , other);
122- link_to (actor_cast<strong_actor_ptr>(other));
123- }
124-
125120void abstract_actor::unlink_from (const actor_addr& other) {
126121 auto lg = log::core::trace (" other = {}" , other);
127- if (! other)
122+ if (other. id () == invalid_actor_id )
128123 return ;
129- if (auto hdl = actor_cast<strong_actor_ptr>(other)) {
130- unlink_from (hdl);
124+ // Try to resolve `other` to a weak pointer.
125+ weak_actor_ptr other_ptr;
126+ exclusive_critical_section ([this , &other, &other_ptr] { //
127+ internal::attachable_predicate::extractor extractor{&other, &other_ptr};
128+ auto pred = internal::attachable_predicate::linked_to (&extractor);
129+ std::ignore = this ->attachables_ .any_of (pred);
130+ });
131+ // If there's no link attachable for `other`, we're done.
132+ if (!other_ptr) {
133+ return ;
134+ }
135+ // If `other` is still alive, unlink by calling remove_link.
136+ if (auto hdl = other_ptr.lock ()) {
137+ CAF_ASSERT (hdl.get () != ctrl ());
138+ remove_link (hdl->get ());
131139 return ;
132140 }
133141 // Promoting weak to strong reference fails if-and-only-if the strong
134142 // reference count is already at 0 which means the other actor must have
135- // terminated. However, we call this overload automatically after receiving an
136- // exit message to clean up leftover state.
137- auto pred = internal::attachable_predicate::linked_to ( other. ptr (). ctrl ()) ;
138- exclusive_critical_section ([ this , & pred] { //
143+ // terminated already. Clean up leftover state.
144+ exclusive_critical_section ([ this , &other] { //
145+ internal::attachable_predicate::extractor extractor{& other, nullptr } ;
146+ auto pred = internal::attachable_predicate::linked_to (&extractor);
139147 attachables_.erase_first_if (pred);
140148 });
141149}
@@ -160,7 +168,7 @@ actor_system& abstract_actor::home_system() const noexcept {
160168}
161169
162170actor_addr abstract_actor::address () const noexcept {
163- return actor_addr{ctrl_, add_ref };
171+ return { id (), node () };
164172}
165173
166174abstract_actor* abstract_actor::current () noexcept {
@@ -239,7 +247,8 @@ void abstract_actor::add_link(abstract_actor* x) {
239247 CAF_ASSERT (x != nullptr );
240248 error fail_state;
241249 bool send_exit_immediately = false ;
242- auto tmp = internal::attachable_factory::make_link (x->address ());
250+ auto tmp = internal::attachable_factory::make_link (
251+ weak_actor_ptr{x->ctrl (), add_ref});
243252 joined_exclusive_critical_section (this , x, [&] {
244253 if (getf (is_terminated_flag)) {
245254 fail_state = fail_state_;
@@ -276,7 +285,8 @@ bool abstract_actor::add_backlink(abstract_actor* x) {
276285 }
277286 auto pred = internal::attachable_predicate::linked_to (x->ctrl ());
278287 if (!attachables_.any_of (pred)) {
279- auto tmp = internal::attachable_factory::make_link (x->address ());
288+ auto tmp = internal::attachable_factory::make_link (
289+ weak_actor_ptr{x->ctrl (), add_ref});
280290 attachables_.push (std::move (tmp));
281291 return true ;
282292 }
@@ -293,7 +303,7 @@ bool abstract_actor::remove_backlink(abstract_actor* x) {
293303void abstract_actor::clear_incoming_edges (const actor_addr& other) {
294304 auto lg = log::core::trace (" other = {}" , other);
295305 exclusive_critical_section ([this , &other] { //
296- auto iter = incoming_edges_.find (other. ptr (). ctrl () );
306+ auto iter = incoming_edges_.find (other);
297307 if (iter != incoming_edges_.end ()) {
298308 incoming_edges_.erase (iter);
299309 }
0 commit comments