decorated_tuple::decorated_tuple(cow_ptr&& d, vector_type&& v) : decorated_(std::move(d)), mapping_(std::move(v)), type_token_(0xFFFFFFFF) { CAF_ASSERT(mapping_.empty() || *(std::max_element(mapping_.begin(), mapping_.end())) < static_cast<const cow_ptr&>(decorated_)->size()); // calculate type token for (size_t i = 0; i < mapping_.size(); ++i) { type_token_ <<= 6; type_token_ |= decorated_->type_nr_at(mapping_[i]); } }
message message::drop(size_t n) const { CAF_ASSERT(vals_); if (n == 0) { return *this; } if (n >= size()) { return message{}; } std::vector<size_t> mapping (size() - n); size_t i = n; std::generate(mapping.begin(), mapping.end(), [&] { return i++; }); return message {detail::decorated_tuple::make(vals_, mapping)}; }
// acquires both locks void prepend(pointer value) { CAF_ASSERT(value != nullptr); node* tmp = new node(value); node* first = nullptr; // acquire both locks since we might touch last_ too lock_guard guard1(head_lock_); lock_guard guard2(tail_lock_); first = head_.load(); CAF_ASSERT(first != nullptr); auto next = first->next.load(); // first_ always points to a dummy with no value, // hence we put the new element second if (next) { CAF_ASSERT(first != tail_); tmp->next = next; } else { // queue is empty CAF_ASSERT(first == tail_); tail_ = tmp; } first->next = tmp; }
bool downstream_manager::check_paths_impl(path_algorithm algo, path_predicate&) const noexcept { // Return the result for empty ranges as specified by the C++ standard. switch (algo) { default: CAF_ASSERT(algo == path_algorithm::all_of); return true; case path_algorithm::any_of: return false; case path_algorithm::none_of: return true; } }
decorated_tuple::decorated_tuple(cow_ptr&& d, vector_type&& v) : m_decorated(std::move(d)), m_mapping(std::move(v)), m_type_token(0xFFFFFFFF) { CAF_ASSERT(m_mapping.empty() || *(std::max_element(m_mapping.begin(), m_mapping.end())) < static_cast<const cow_ptr&>(m_decorated)->size()); // calculate type token for (size_t i = 0; i < m_mapping.size(); ++i) { m_type_token <<= 6; m_type_token |= m_decorated->type_nr_at(m_mapping[i]); } }
bool synchronized_await(Mutex& mtx, CondVar& cv, const TimePoint& timeout) { CAF_ASSERT(!closed()); if (try_block()) { std::unique_lock<Mutex> guard(mtx); while (blocked()) { if (cv.wait_until(guard, timeout) == std::cv_status::timeout) { // if we're unable to set the queue from blocked to empty, // than there's a new element in the list return !try_unblock(); } } } return true; }
actor actor::splice_impl(std::initializer_list<actor> xs) { CAF_ASSERT(xs.size() >= 2); actor_system* sys = nullptr; std::vector<strong_actor_ptr> tmp; for (auto& x : xs) { if (! sys) sys = &(x->home_system()); tmp.push_back(actor_cast<strong_actor_ptr>(x)); } return make_actor<decorator::splitter, actor>(sys->next_actor_id(), sys->node(), sys, std::move(tmp), std::set<std::string>{}); }
bool abstract_actor::link_impl(linking_operation op, const actor_addr& other) { CAF_LOG_TRACE(CAF_ARG(op) << ", " << CAF_TSARG(other)); switch (op) { case establish_link_op: return establish_link_impl(other); case establish_backlink_op: return establish_backlink_impl(other); case remove_link_op: return remove_link_impl(other); default: CAF_ASSERT(op == remove_backlink_op); return remove_backlink_impl(other); } }
void run() { CAF_SET_LOGGER_SYS(&system()); CAF_LOG_TRACE(CAF_ARG(id_)); // scheduling loop for (;;) { auto job = policy_.dequeue(this); CAF_ASSERT(job != nullptr); CAF_ASSERT(job->subtype() != resumable::io_actor); CAF_LOG_DEBUG("resume actor:" << CAF_ARG(id_of(job))); CAF_PUSH_AID_FROM_PTR(dynamic_cast<abstract_actor*>(job)); policy_.before_resume(this, job); auto res = job->resume(this, max_throughput_); policy_.after_resume(this, job); switch (res) { case resumable::resume_later: { // keep reference to this actor, as it remains in the "loop" policy_.resume_job_later(this, job); break; } case resumable::done: { policy_.after_completion(this, job); intrusive_ptr_release(job); break; } case resumable::awaiting_message: { // resumable will maybe be enqueued again later, deref it for now intrusive_ptr_release(job); break; } case resumable::shutdown_execution_unit: { policy_.after_completion(this, job); policy_.before_shutdown(this); return; } } } }
void scribe::consume(execution_unit* ctx, const void*, size_t num_bytes) { CAF_ASSERT(ctx != nullptr); CAF_LOG_TRACE(CAF_ARG(num_bytes)); if (detached()) { // we are already disconnected from the broker while the multiplexer // did not yet remove the socket, this can happen if an IO event causes // the broker to call close_all() while the pollset contained // further activities for the broker return; } // keep a strong reference to our parent until we leave scope // to avoid UB when becoming detached during invocation auto guard = parent_; auto& buf = rd_buf(); CAF_ASSERT(buf.size() >= num_bytes); // make sure size is correct, swap into message, and then call client buf.resize(num_bytes); auto& msg_buf = msg().buf; msg_buf.swap(buf); invoke_mailbox_element(ctx); // swap buffer back to stream and implicitly flush wr_buf() msg_buf.swap(buf); flush(); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void CmdAddItemFeature::onActionTriggered(bool isChecked) { if (isCommandEnabled()) { CmdExecuteCommand* exeCmd = createExecuteCommand(); if (exeCmd) { CmdExecCommandManager::instance()->processExecuteCommand(exeCmd); } else { CAF_ASSERT(0); } } }
std::vector<iface_info> get_mac_addresses() { int mib[6]; std::vector<iface_info> result; mib[0] = CTL_NET; mib[1] = AF_ROUTE; mib[2] = 0; mib[3] = AF_LINK; mib[4] = NET_RT_IFLIST; auto indices = if_nameindex(); std::vector<char> buf; for (auto i = indices; !(i->if_index == 0 && i->if_name == nullptr); ++i) { mib[5] = static_cast<int>(i->if_index); size_t len; if (sysctl(mib, 6, nullptr, &len, nullptr, 0) < 0) { perror("sysctl 1 error"); exit(3); } if (buf.size() < len) buf.resize(len); CAF_ASSERT(len > 0); if (sysctl(mib, 6, buf.data(), &len, nullptr, 0) < 0) { perror("sysctl 2 error"); exit(5); } auto ifm = reinterpret_cast<if_msghdr*>(buf.data()); auto sdl = reinterpret_cast<sockaddr_dl*>(ifm + 1); auto ptr = reinterpret_cast<unsigned char*>(LLADDR(sdl)); auto uctoi = [](unsigned char c) -> unsigned { return static_cast<unsigned char>(c); }; std::ostringstream oss; oss << std::hex; oss.fill('0'); oss.width(2); oss << uctoi(*ptr++); for (auto j = 0; j < 5; ++j) { oss << ":"; oss.width(2); oss << uctoi(*ptr++); } auto addr = oss.str(); if (addr != "00:00:00:00:00:00") { result.emplace_back(i->if_name, std::move(addr)); } } if_freenameindex(indices); return result; }
void monitorable_actor::attach(attachable_ptr ptr) { CAF_LOG_TRACE(""); CAF_ASSERT(ptr != nullptr); error fail_state; auto attached = exclusive_critical_section([&] { if (getf(is_terminated_flag)) { fail_state = fail_state_; return false; } attach_impl(ptr); return true; }); CAF_LOG_DEBUG("cannot attach functor to terminated actor: call immediately"); if (!attached) ptr->actor_exited(fail_state, nullptr); }
void replace_all(std::string& str, const char (&what)[WhatSize], const char (&with)[WithSize]) { // end(what) - 1 points to the null-terminator auto next = [&](std::string::iterator pos) -> std::string::iterator { return std::search(pos, str.end(), std::begin(what), std::end(what) - 1); }; auto i = next(std::begin(str)); while (i != std::end(str)) { auto before = std::distance(std::begin(str), i); CAF_ASSERT(before >= 0); str.replace(i, i + WhatSize - 1, with); // i became invalidated -> use new iterator pointing // to the first character after the replaced text i = next(str.begin() + before + (WithSize - 1)); } }
/// Tries to enqueue a new element to the inbox. /// @threadsafe inbox_result push_front(pointer new_element) noexcept { CAF_ASSERT(new_element != nullptr); pointer e = stack_.load(); auto eof = stack_closed_tag(); auto blk = reader_blocked_tag(); while (e != eof) { // A tag is never part of a non-empty list. new_element->next = e != blk ? e : nullptr; if (stack_.compare_exchange_strong(e, new_element)) return e == reader_blocked_tag() ? inbox_result::unblocked_reader : inbox_result::success; // Continue with new value of `e`. } // The queue has been closed, drop messages. deleter_type d; d(new_element); return inbox_result::queue_closed; }
/// Tries to enqueue a new element to the mailbox. /// @warning Call only from the reader (owner). enqueue_result enqueue(pointer new_element) { CAF_ASSERT(new_element != nullptr); pointer e = stack_.load(); for (;;) { if (! e) { // if tail is nullptr, the queue has been closed delete_(new_element); return enqueue_result::queue_closed; } // a dummy is never part of a non-empty list new_element->next = is_dummy(e) ? nullptr : e; if (stack_.compare_exchange_strong(e, new_element)) { return (e == reader_blocked_dummy()) ? enqueue_result::unblocked_reader : enqueue_result::success; } // continue with new value of e } }
void monitorable_actor::add_link(abstract_actor* x) { // Add backlink on `x` first and add the local attachable only on success. CAF_LOG_TRACE(CAF_ARG(x)); CAF_ASSERT(x != nullptr); error fail_state; bool send_exit_immediately = false; auto tmp = default_attachable::make_link(address(), x->address()); joined_exclusive_critical_section(this, x, [&] { if (getf(is_terminated_flag)) { fail_state = fail_state_; send_exit_immediately = true; } else if (x->add_backlink(this)) { attach_impl(tmp); } }); if (send_exit_immediately) x->enqueue(nullptr, invalid_message_id, make_message(exit_msg{address(), fail_state}), nullptr); }
actor_addr actor_namespace::read(deserializer* source) { CAF_ASSERT(source != nullptr); node_id::host_id_type hid; auto aid = source->read<uint32_t>(); // actor id source->read_raw(node_id::host_id_size, hid.data()); // host id auto pid = source->read<uint32_t>(); // process id node_id this_node = detail::singletons::get_node_id(); if (aid == 0 && pid == 0) { // 0:0 identifies an invalid actor return invalid_actor_addr; } if (pid == this_node.process_id() && hid == this_node.host_id()) { // identifies this exact process on this host, ergo: local actor auto a = detail::singletons::get_actor_registry()->get(aid); // might be invalid return a ? a->address() : invalid_actor_addr; } // identifies a remote actor; create proxy if needed return get_or_put({pid, hid}, aid)->address(); }
void actor_namespace::write(serializer* sink, const actor_addr& addr) { CAF_ASSERT(sink != nullptr); if (! addr) { node_id::host_id_type zero; std::fill(zero.begin(), zero.end(), 0); sink->write_value(static_cast<actor_id>(0)); // actor id sink->write_raw(node_id::host_id_size, zero.data()); // host id sink->write_value(static_cast<uint32_t>(0)); // process id } else { // register locally running actors to be able to deserialize them later if (! addr.is_remote()) { auto reg = detail::singletons::get_actor_registry(); reg->put(addr.id(), actor_cast<abstract_actor_ptr>(addr)); } auto pinf = addr.node(); sink->write_value(addr.id()); // actor id sink->write_raw(node_id::host_id_size, pinf.host_id().data()); // host id sink->write_value(pinf.process_id()); // process id } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void PdmUiFieldHandle::notifyFieldChanged(const QVariant& oldFieldValue, const QVariant& newFieldValue) { if (oldFieldValue != newFieldValue) { PdmFieldHandle* fieldHandle = this->fieldHandle(); CAF_ASSERT(fieldHandle && fieldHandle->ownerObject()); PdmUiObjectHandle* uiObjHandle = uiObj(fieldHandle->ownerObject()); if (uiObjHandle) { uiObjHandle->fieldChangedByUi(fieldHandle, oldFieldValue, newFieldValue); uiObjHandle->updateConnectedEditors(); } // Update field editors this->updateConnectedEditors(); PdmUiModelChangeDetector::instance()->setModelChanged(); } }
void logger::run() { std::ostringstream fname; fname << "actor_log_" << detail::get_process_id() << "_" << time(0) << "_" << to_string(system_.node()) << ".log"; std::fstream out(fname.str().c_str(), std::ios::out | std::ios::app); std::unique_ptr<event> ptr; for (;;) { // make sure we have data to read queue_.synchronized_await(queue_mtx_, queue_cv_); // read & process event ptr.reset(queue_.try_pop()); CAF_ASSERT(ptr != nullptr); if (ptr->msg.empty()) { out.close(); return; } out << ptr->msg << std::flush; } }
void abstract_actor::cleanup(uint32_t reason) { CAF_LOG_TRACE(CAF_ARG(reason)); CAF_ASSERT(reason != exit_reason::not_exited); // move everyhting out of the critical section before processing it attachable_ptr head; { // lifetime scope of guard guard_type guard{mtx_}; if (exit_reason_ != exit_reason::not_exited) { // already exited return; } exit_reason_ = reason; attachables_head_.swap(head); } CAF_LOG_INFO_IF(! is_remote(), "cleanup actor with ID " << id_ << "; exit reason = " << reason); // send exit messages for (attachable* i = head.get(); i != nullptr; i = i->next.get()) { i->actor_exited(this, reason); } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void PdmUiDateEditor::configureAndUpdateUi(const QString& uiConfigName) { CAF_ASSERT(!m_dateEdit.isNull()); PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName); m_dateEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); if (uiObject) { uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &m_attributes); } if (!m_attributes.dateFormat.isEmpty()) { m_dateEdit->setDisplayFormat(m_attributes.dateFormat); } m_dateEdit->setDate(field()->uiValue().toDate()); }
bool monitorable_actor::add_backlink(abstract_actor* x) { // Called in an exclusive critical section. CAF_LOG_TRACE(CAF_ARG(x)); CAF_ASSERT(x); error fail_state; bool send_exit_immediately = false; default_attachable::observe_token tk{x->address(), default_attachable::link}; auto tmp = default_attachable::make_link(address(), x->address()); auto success = false; if (getf(is_terminated_flag)) { fail_state = fail_state_; send_exit_immediately = true; } else if (detach_impl(tk, true, true) == 0) { attach_impl(tmp); success = true; } if (send_exit_immediately) x->enqueue(nullptr, invalid_message_id, make_message(exit_msg{address(), fail_state}), nullptr); return success; }
const uniform_type_info* uniform_typeid_by_nr(uint16_t nr) { CAF_ASSERT(nr > 0 && nr < detail::type_nrs); return uti_map().by_type_nr(nr); }
error decorated_tuple::save(size_t pos, serializer& sink) const { CAF_ASSERT(pos < size()); return decorated_->save(mapping_[pos], sink); }
type_erased_value_ptr decorated_tuple::copy(size_t pos) const { CAF_ASSERT(pos < size()); return decorated_->copy(mapping_[pos]); }
std::string decorated_tuple::stringify(size_t pos) const { CAF_ASSERT(pos < size()); return decorated_->stringify(mapping_[pos]); }
const void* decorated_tuple::get(size_t pos) const noexcept { CAF_ASSERT(pos < size()); return decorated_->get(mapping_[pos]); }
message_data::rtti_pair decorated_tuple::type(size_t pos) const noexcept { CAF_ASSERT(pos < size()); return decorated_->type(mapping_[pos]); }