\doxysection{osmo\+\_\+use\+\_\+count Struct Reference}
\label{structosmo__use__count}\index{osmo\_use\_count@{osmo\_use\_count}}


Use counter state for one used object, managing N distinct named counters.  




{\ttfamily \#include $<$use\+\_\+count.\+h$>$}

\doxysubsection*{Data Fields}
\begin{DoxyCompactItemize}
\item 
void $\ast$ \textbf{ talloc\+\_\+object}
\begin{DoxyCompactList}\small\item\em Context to talloc-\/allocate use count entries from (if at all necessary); back-\/pointer to the owning object for osmo\+\_\+use\+\_\+count\+\_\+cb\+\_\+t implementations. \end{DoxyCompactList}\item 
\textbf{ osmo\+\_\+use\+\_\+count\+\_\+cb\+\_\+t} \textbf{ use\+\_\+cb}
\begin{DoxyCompactList}\small\item\em If not NULL, this is invoked for each use count change. \end{DoxyCompactList}\item 
struct \textbf{ llist\+\_\+head} \textbf{ use\+\_\+counts}
\begin{DoxyCompactList}\small\item\em List of use tokens. \end{DoxyCompactList}\end{DoxyCompactItemize}


\doxysubsection{Detailed Description}
Use counter state for one used object, managing N distinct named counters. 

Manage any number of uses of an object, with name tokens given to each use.

A typical use tracking done by a single instance of this struct may look like\+: \char`\"{}\+VLR subscr MSISDN-\/23 + SMS-\/receiver\+: now used by 6 (attached,2$\ast$\+SMS-\/receiver,\+SMS-\/pending,\+SMS,\+Paging)\char`\"{} (This is a DREF log statement from an osmo-\/msc run delivering an SMS.)

Use tokens are given as const char$\ast$ strings. Typically string literals like \char`\"{}foo\char`\"{}, {\bfseries{func}}, or also NULL. Tokens may be dynamically allocated or static char[] buffers as long as they are guaranteed to remain unchanged while referenced by an \doxyref{osmo\+\_\+use\+\_\+count\+\_\+entry}{p.}{structosmo__use__count__entry}. (Breakage occurs if one token magically changes to equal another listed token.)

Instead of using string literals in the code directly, callers should use a \#define, so that typos are caught at compile time rather than introducing obscure failures that are hard to spot for humans -- don\textquotesingle{}t use foo\+\_\+get(\char`\"{}bar\char`\"{}) and foo\+\_\+put(\char`\"{}bar\char`\"{}), but \textquotesingle{}\#define FOO\+\_\+\+USE\+\_\+\+BAR \char`\"{}bar\char`\"{}\textquotesingle{} for foo\+\_\+get(\+FOO\+\_\+\+USE\+\_\+\+BAR) and foo\+\_\+put(\+FOO\+\_\+\+USE\+\_\+\+BAR).

Counts are int32\+\_\+t values, a separate count per use token string. Counts can be negative, though in the typical use case are only positive or 0. Enforcing a range is entirely up to the \doxyref{osmo\+\_\+use\+\_\+count\+\_\+cb\+\_\+t()}{p.}{group__use__count_ga4497d9dc69e733d16d33a455d385931e} implementation.

The talloc\+\_\+object must be a pointer eligible to be a talloc context, i.\+e. either obtained from a function like talloc\+\_\+zero() or NULL. talloc\+\_\+object is typically a pointer to the object that this struct is a member of. Use count entries may be allocated as talloc children of this (see also \char`\"{}\+Avoiding dynamic allocation\char`\"{} below).

The \doxyref{use\+\_\+cb()}{p.}{structosmo__use__count_ae3ae970b037b9f0828bd4b4b5d84b248} implementation allows to trigger actions when reaching specific use counts, e.\+g. deallocate when reaching a total sum across all use tokens of zero.

On initialization, this struct can be left fully zero initialized (the \doxyref{llist\+\_\+head}{p.}{structllist__head} use\+\_\+counts is implicitly initialized upon the first \doxyref{osmo\+\_\+use\+\_\+count\+\_\+get\+\_\+put()}{p.}{group__use__count_ga3457c05c5d2b707d99eb01704dc5f233}). Usually, set only a talloc\+\_\+object and a use\+\_\+cb, though neither is strictly required.

Avoiding dynamic allocation\+: dynamic allocation can be avoided completely by providing sufficient static use count entries with \doxyref{osmo\+\_\+use\+\_\+count\+\_\+make\+\_\+static\+\_\+entries()}{p.}{group__use__count_ga1d3601b4f5093407d57ca3f5e1c093cc}. Otherwise, each new use token will dynamically allocate a new \doxyref{osmo\+\_\+use\+\_\+count\+\_\+entry}{p.}{structosmo__use__count__entry}; note that once allocated, these entries stay around even if they reached an entry count of zero, and will be re-\/used for subsequent use count tokens. So even if not using \doxyref{osmo\+\_\+use\+\_\+count\+\_\+make\+\_\+static\+\_\+entries()}{p.}{group__use__count_ga1d3601b4f5093407d57ca3f5e1c093cc}, each \doxyref{osmo\+\_\+use\+\_\+count}{p.}{structosmo__use__count} will keep dynamic allocations at a minimum. See also the documentation for osmo\+\_\+use\+\_\+count\+\_\+cb\+\_\+t.

List traversal considerations\+: your typical use count list would max at about six entries in practice. Traversing six llist-\/$>$next pointers is less effort than doing a common strlen().

Obtaining the total use count\+: \doxyref{osmo\+\_\+use\+\_\+count\+\_\+total()}{p.}{group__use__count_ga34703c11c4da78bebd3322635b57e698} traverses all use token entries and forms a sum. It is trivial to keep a separate total count that completely avoids the need for calling this function, which is entirely up to the individual \doxyref{osmo\+\_\+use\+\_\+count\+\_\+cb\+\_\+t()}{p.}{group__use__count_ga4497d9dc69e733d16d33a455d385931e} implementation. The optimization gained is usually not worth it, though.

Use token comparison considerations\+: strcmp() to compare use tokens is a fairly good tradeoff\+:
\begin{DoxyItemize}
\item when the strings differ, strcmp() usually exits on the first or second character.
\item when the strings are identical, they are usually the exact same char$\ast$ address (from compile-\/time string constant), meaning that strcmp() is completely skipped. (quote\+: \char`\"{}if (e-\/$>$use == use $\vert$$\vert$ (use \&\& e-\/$>$use \&\& !strcmp(e-\/$>$use, use)))\char`\"{})
\item if we specified compile-\/time string constant use as requirement, we wouldn\textquotesingle{}t need strcmp() at all, but this minuscule overhead has the benefit of complete correctness for any kinds of use token strings.
\end{DoxyItemize}

Example\+: \begin{DoxyVerb}struct foo {
        struct osmo_use_count use_count;
};

// Convenience macros for struct foo instances. These are strict about use count errors.
#define foo_get(FOO, USE) OSMO_ASSERT( osmo_use_count_get_put(&(FOO)->use_count, USE, 1) == 0 );
#define foo_put(FOO, USE) OSMO_ASSERT( osmo_use_count_get_put(&(FOO)->use_count, USE, -1) == 0 );

int foo_use_cb(struct osmo_use_count_entry *use_count_entry, int32_t old_use_count, const char *file, int line)
{
        struct foo *foo = use_count_entry->use_count->talloc_object;
        if (osmo_use_count_total(use_count_entry->use_count) == 0)
                talloc_free(foo);
        return 0;
}

// The function name is a convenient use token:
void rx_stop_baz_request(struct foo *foo)
{
        foo_get(foo, __func__);

        foo_put(foo, "baz");
        printf("Stopped Bazing (%p)\n", foo);

        foo_put(foo, __func__);
}

void use_count_example()
{
        struct foo *foo = talloc_zero(ctx, struct foo);
        *foo = (struct foo){
                .use_count = {
                        .talloc_object = foo,
                        .use_cb = foo_use_cb,
                },
        };

        foo_get(foo, "bar");       // one osmo_use_count_entry was allocated
        foo_get(foo, "baz");       // a second osmo_use_count_entry was allocated
        foo_get(foo, "baz");       // still two entries

        printf("use: %s\n", osmo_use_count_name_buf(namebuf, sizeof(namebuf), &foo->use_count));
        // "use: 3 (bar,2*baz)"

        foo_put(foo, "bar");       // still two entries, one entry is idle ("bar"=0)
        foo_put(foo, "baz");
        rx_stop_baz_request(foo);
        // Final "baz" was put(), foo_use_cb() deallocated object foo, as well as all use count entries.
};
\end{DoxyVerb}
 

\doxysubsection{Field Documentation}
\mbox{\label{structosmo__use__count_a931dcee6ec7160ea3dda64f6190d0a7e}} 
\index{osmo\_use\_count@{osmo\_use\_count}!talloc\_object@{talloc\_object}}
\index{talloc\_object@{talloc\_object}!osmo\_use\_count@{osmo\_use\_count}}
\doxysubsubsection{talloc\_object}
{\footnotesize\ttfamily void$\ast$ osmo\+\_\+use\+\_\+count\+::talloc\+\_\+object}



Context to talloc-\/allocate use count entries from (if at all necessary); back-\/pointer to the owning object for osmo\+\_\+use\+\_\+count\+\_\+cb\+\_\+t implementations. 



Referenced by \textbf{ osmo\+\_\+use\+\_\+count\+\_\+create()}.

\mbox{\label{structosmo__use__count_ae3ae970b037b9f0828bd4b4b5d84b248}} 
\index{osmo\_use\_count@{osmo\_use\_count}!use\_cb@{use\_cb}}
\index{use\_cb@{use\_cb}!osmo\_use\_count@{osmo\_use\_count}}
\doxysubsubsection{use\_cb}
{\footnotesize\ttfamily \textbf{ osmo\+\_\+use\+\_\+count\+\_\+cb\+\_\+t} osmo\+\_\+use\+\_\+count\+::use\+\_\+cb}



If not NULL, this is invoked for each use count change. 



Referenced by \textbf{ \+\_\+osmo\+\_\+use\+\_\+count\+\_\+get\+\_\+put()}.

\mbox{\label{structosmo__use__count_a2e13cc69cf4792e3260368102e6d4ee8}} 
\index{osmo\_use\_count@{osmo\_use\_count}!use\_counts@{use\_counts}}
\index{use\_counts@{use\_counts}!osmo\_use\_count@{osmo\_use\_count}}
\doxysubsubsection{use\_counts}
{\footnotesize\ttfamily struct \textbf{ llist\+\_\+head} osmo\+\_\+use\+\_\+count\+::use\+\_\+counts}



List of use tokens. 

No need to touch this, the llist is initialized implicitly. 

Referenced by \textbf{ \+\_\+osmo\+\_\+use\+\_\+count\+\_\+get\+\_\+put()}, \textbf{ osmo\+\_\+use\+\_\+count\+\_\+create()}, \textbf{ osmo\+\_\+use\+\_\+count\+\_\+find()}, \textbf{ osmo\+\_\+use\+\_\+count\+\_\+make\+\_\+static\+\_\+entries()}, \textbf{ osmo\+\_\+use\+\_\+count\+\_\+repurpose\+\_\+zero\+\_\+entry()}, \textbf{ osmo\+\_\+use\+\_\+count\+\_\+to\+\_\+str\+\_\+buf()}, and \textbf{ osmo\+\_\+use\+\_\+count\+\_\+total()}.



The documentation for this struct was generated from the following file\+:\begin{DoxyCompactItemize}
\item 
include/osmocom/core/\textbf{ use\+\_\+count.\+h}\end{DoxyCompactItemize}
