From: Jérémie Galarneau Date: Thu, 5 May 2022 19:25:39 +0000 (-0400) Subject: sessiond: add smart pointer utils for ltt_session X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=e99e366487cb113a1041e4217ba181feb52d05c9;p=deliverable%2Flttng-tools.git sessiond: add smart pointer utils for ltt_session Add `find_session_by_id` and `find_locked_session_by_id` which return smart pointers to ltt_session. In both cases, the smart pointers make use of ltt_session's underlying reference counting mechanism. In the case of `find_locked_session_by_id`, the session that is returned is locked; it is automatically unlocked (and a reference is released) when the pointer goes out of scope. This makes it easier to write exception-safe code that uses the ltt_session API. Signed-off-by: Jérémie Galarneau Change-Id: I125dc7592b8ef2de1da645029f311bf429a21767 --- diff --git a/src/bin/lttng-sessiond/session.cpp b/src/bin/lttng-sessiond/session.cpp index d8accb87d..1846024fc 100644 --- a/src/bin/lttng-sessiond/session.cpp +++ b/src/bin/lttng-sessiond/session.cpp @@ -6,30 +6,32 @@ */ #define _LGPL_SOURCE -#include +#include #include +#include +#include #include #include #include #include -#include -#include #include -#include +#include #include -#include -#include #include -#include +#include +#include +#include + #include "lttng-sessiond.hpp" -#include "kernel.hpp" +#include +#include "cmd.hpp" +#include "kernel.hpp" #include "session.hpp" -#include "utils.hpp" -#include "trace-ust.hpp" #include "timer.hpp" -#include "cmd.hpp" +#include "trace-ust.hpp" +#include "utils.hpp" namespace { struct ltt_session_destroy_notifier_element { @@ -42,6 +44,8 @@ struct ltt_session_clear_notifier_element { void *user_data; }; +namespace ls = lttng::sessiond; + /* * NOTES: * @@ -1461,3 +1465,38 @@ end: rcu_read_unlock(); return found; } + +void ls::details::locked_session_release(ltt_session *session) +{ + session_unlock(session); + session_put(session); +} + +ltt_session::locked_ptr ls::find_locked_session_by_id(ltt_session::id_t id) +{ + lttng::urcu::read_lock_guard rcu_lock; + auto session = session_find_by_id(id); + + if (!session) { + return nullptr; + } + + /* + * The pointer falling out of scope will unlock and release the reference to the + * session. + */ + session_lock(session); + return ltt_session::locked_ptr(session); +} + +ltt_session::sptr ls::find_session_by_id(ltt_session::id_t id) +{ + lttng::urcu::read_lock_guard rcu_lock; + auto session = session_find_by_id(id); + + if (!session) { + return nullptr; + } + + return {session, session_put}; +} diff --git a/src/bin/lttng-sessiond/session.hpp b/src/bin/lttng-sessiond/session.hpp index ad451336a..17f3ca139 100644 --- a/src/bin/lttng-sessiond/session.hpp +++ b/src/bin/lttng-sessiond/session.hpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -31,6 +32,14 @@ typedef void (*ltt_session_destroy_notifier)(const struct ltt_session *session, typedef void (*ltt_session_clear_notifier)(const struct ltt_session *session, void *user_data); +namespace lttng { +namespace sessiond { +namespace details { +void locked_session_release(ltt_session *session); +} /* namespace details */ +} /* namespace sessiond */ +} /* namespace lttng */ + /* * Tracing session list * @@ -67,6 +76,12 @@ struct ltt_session_list { * session for both LTTng and UST. */ struct ltt_session { + using id_t = uint64_t; + using locked_ptr = std::unique_ptr::deleter>; + using sptr = std::shared_ptr; + char name[NAME_MAX]; bool has_auto_generated_name; bool name_contains_creation_time; @@ -84,7 +99,8 @@ struct ltt_session { */ pthread_mutex_t lock; struct cds_list_head list; - uint64_t id; /* session unique identifier */ + /* session unique identifier */ + id_t id; /* Indicates if the session has been added to the session list and ht.*/ bool published; /* Indicates if a destroy command has been applied to this session. */ @@ -240,7 +256,7 @@ struct lttng_trace_archive_location *session_get_trace_archive_location( const struct ltt_session *session); struct ltt_session *session_find_by_name(const char *name); -struct ltt_session *session_find_by_id(uint64_t id); +struct ltt_session *session_find_by_id(ltt_session::id_t id); struct ltt_session_list *session_get_list(void); void session_list_wait_empty(void); @@ -294,4 +310,26 @@ bool session_output_supports_trace_chunks(const struct ltt_session *session); */ bool sample_session_id_by_name(const char *name, uint64_t *id); +namespace lttng { +namespace sessiond { + +/* + * Session list lock must be acquired by the caller. + * The caller must not keep the ownership of the returned locked session + * for longer than strictly necessary. If your intention is to acquire + * a reference to an ltt_session, see `find_session_by_id()`. + */ +ltt_session::locked_ptr find_locked_session_by_id(ltt_session::id_t id); + +/* + * Session list lock must be acquired by the caller. + * The caller must not keep the ownership of the returned locked session + * for longer than strictly necessary. If your intention is to acquire + * a reference to an ltt_session, see `find_session_by_id()`. + */ +ltt_session::sptr find_session_by_id(ltt_session::id_t id); + +} /* namespace sessiond */ +} /* namespace lttng */ + #endif /* _LTT_SESSION_H */