lttng_action objects will be shared with the action executor subsystem
which executes them asynchronously. This introduces an ambiguous
ownership since triggers could be unregistered while an action is
executing (or pending execution).
Also ease the object ownership management of the group action sub
actions. This allow clients to add multiple time the same action to an
action group without any problem.
The currently user-visible 'destroy' method simply calls the 'put'
method which preserves the expected behaviour for current users (both
internal and public) of the API.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I2d016a9b80e418d40c72db8e155c44e96852b33f
#include <common/sessiond-comm/payload.h>
#include <stdbool.h>
#include <sys/types.h>
#include <common/sessiond-comm/payload.h>
#include <stdbool.h>
#include <sys/types.h>
typedef bool (*action_validate_cb)(struct lttng_action *action);
typedef void (*action_destroy_cb)(struct lttng_action *action);
typedef bool (*action_validate_cb)(struct lttng_action *action);
typedef void (*action_destroy_cb)(struct lttng_action *action);
struct lttng_action **action);
struct lttng_action {
struct lttng_action **action);
struct lttng_action {
enum lttng_action_type type;
action_validate_cb validate;
action_serialize_cb serialize;
enum lttng_action_type type;
action_validate_cb validate;
action_serialize_cb serialize;
bool lttng_action_is_equal(const struct lttng_action *a,
const struct lttng_action *b);
bool lttng_action_is_equal(const struct lttng_action *a,
const struct lttng_action *b);
+LTTNG_HIDDEN
+void lttng_action_get(struct lttng_action *action);
+
+LTTNG_HIDDEN
+void lttng_action_put(struct lttng_action *action);
+
#endif /* LTTNG_ACTION_INTERNAL_H */
#endif /* LTTNG_ACTION_INTERNAL_H */
action_equal_cb equal,
action_destroy_cb destroy)
{
action_equal_cb equal,
action_destroy_cb destroy)
{
+ urcu_ref_init(&action->ref);
action->type = type;
action->validate = validate;
action->serialize = serialize;
action->type = type;
action->validate = validate;
action->serialize = serialize;
action->destroy = destroy;
}
action->destroy = destroy;
}
-void lttng_action_destroy(struct lttng_action *action)
+static
+void action_destroy_ref(struct urcu_ref *ref)
+{
+ struct lttng_action *action =
+ container_of(ref, struct lttng_action, ref);
+
+ action->destroy(action);
+}
+
+LTTNG_HIDDEN
+void lttng_action_get(struct lttng_action *action)
+{
+ urcu_ref_get(&action->ref);
+}
+
+LTTNG_HIDDEN
+void lttng_action_put(struct lttng_action *action)
{
if (!action) {
return;
}
assert(action->destroy);
{
if (!action) {
return;
}
assert(action->destroy);
- action->destroy(action);
+ urcu_ref_put(&action->ref, action_destroy_ref);
+}
+
+void lttng_action_destroy(struct lttng_action *action)
+{
+ lttng_action_put(action);