in src/LttngHelpers.c [465:528]
int lttngh_RegisterProvider(
lttngh_registration* pRegistration,
lttngh_ust_probe_desc *pProbeDesc,
struct lttng_ust_tracepoint **pTracepointStart,
struct lttng_ust_tracepoint **pTracepointStop,
lttngh_ust_event_desc const **pEventDescStart,
lttngh_ust_event_desc const **pEventDescStop)
{
int err;
int volatile* const pIsRegistered = lttngh_REGISTRATION_STATE(*pRegistration);
// Note: not intended to support multithreaded or ref-counted registration.
// pRegistration is used to make it safe to call Unregister on an
// unregistered lib and to help detect misuse, not to make this thread-safe.
if (__atomic_exchange_n(pIsRegistered, 1, __ATOMIC_RELAXED) != 0)
{
err = EEXIST;
ProviderError(pProbeDesc, err,
"provider already registered.");
}
else
{
lttngh_ust_event_desc const **const pEventDescLast =
(lttngh_ust_event_desc const **)FixArray(
(void const **)pEventDescStart, (void const **)pEventDescStop);
pProbeDesc->event_desc = pEventDescStart;
pProbeDesc->nr_events = (unsigned)(pEventDescLast - pEventDescStart);
#if lttngh_UST_VER >= 213
pRegistration->registered_probe = lttng_ust_probe_register(pProbeDesc);
pRegistration->tracepoint_start = pTracepointStart;
err = pRegistration->registered_probe ? 0 : ENOMEM;
#else // lttngh_UST_VER
err = lttng_probe_register(pProbeDesc);
#endif // lttngh_UST_VER
if (err != 0)
{
ProviderError(pProbeDesc, err,
"lttng_probe_register failed."
" (Registration of multiple providers having the same name is not supported.)");
__atomic_exchange_n(pIsRegistered, 0, __ATOMIC_RELAXED);
}
else
{
struct lttng_ust_tracepoint *const *const pTracepointLast =
(struct lttng_ust_tracepoint *const *)FixArray(
(void const **)pTracepointStart, (void const **)pTracepointStop);
// May fail for out-of-memory. Continue anyway.
err = lttngh_ust_tracepoint_module_register(pTracepointStart, (int)(pTracepointLast - pTracepointStart));
if (err != 0)
{
#if lttngh_UST_VER >= 213
lttng_ust_probe_unregister(pRegistration->registered_probe);
#else // lttngh_UST_VER
lttng_probe_unregister(pProbeDesc);
#endif // lttngh_UST_VER
__atomic_exchange_n(pIsRegistered, 0, __ATOMIC_RELAXED);
}
}
}
return err;
}