#include "sdbusplus/server/transaction.hpp" namespace sdbusplus { namespace server { namespace transaction { namespace details { // Transaction Id thread_local uint64_t id = 0; } // namespace details uint64_t get_id() { // If the transaction id has not been initialized, generate one. if (!details::id) { details::Transaction t; details::id = std::hash{}(t); } return details::id; } void set_id(uint64_t value) { details::id = value; } void set_id(message::message& msg) { auto tbus = msg.get_bus(); auto t = Transaction(tbus, msg); set_id(std::hash{}(t)); } } // namespace transaction } // namespace server } // namespace sdbusplus namespace std { size_t hash::operator()(sdbusplus::bus::bus& b) const { auto name = b.get_unique_name(); return std::hash{}(name); } size_t hash::operator()( sdbusplus::message::message& m) const { switch (m.get_type()) { // Reply messages will always embed the cookie of the original // message in a separate location. We want to use this cookie // to correlate messages as one transaction. case SD_BUS_MESSAGE_METHOD_RETURN: case SD_BUS_MESSAGE_METHOD_ERROR: return std::hash{}(m.get_reply_cookie()); // Method calls will have the cookie in the header when sealed. // Since we are on the server side that should always be the case. case SD_BUS_MESSAGE_METHOD_CALL: return std::hash{}(m.get_cookie()); // Outgoing signals don't have a cookie so we need to use // something else as an id. Just use a monotonic unique one. case SD_BUS_MESSAGE_SIGNAL: return std::hash{}( std::chrono::steady_clock::now().time_since_epoch().count()); default: throw std::runtime_error("hash message: Unknown message type"); } } size_t hash::operator()( sdbusplus::server::transaction::Transaction const& t) const { auto hash1 = std::hash{}(t.bus); auto hash2 = std::hash{}(t.msg); // boost::hash_combine() algorithm. return static_cast( hash1 ^ (hash2 + 0x9e3779b9 + (hash1 << 6) + (hash1 >> 2))); } size_t hash::operator()( sdbusplus::server::transaction::details::Transaction const& t) const { auto hash1 = std::hash{}(t.time); auto hash2 = std::hash{}(t.thread); // boost::hash_combine() algorithm. return static_cast( hash1 ^ (hash2 + 0x9e3779b9 + (hash1 << 6) + (hash1 >> 2))); } } // namespace std