man rbuf_own (Fonctions bibliothèques) - rbuf ownership

NAME

rbuf_own, rbuf_release, rbuf_owned - rbuf ownership

SYNOPSIS

#include <roy.h>

void rbuf_own (RBuf *buf);

void rbuf_release (RBuf *buf);

int rbuf_owned (RBuf *buf);

RBuf * rbuf_copy_if_owned (RBuf *buf);

DESCRIPTION

This is NOT a full-blown refcount system, so multiple calls to rbuf_own(3) does NOT increment the number of owners. This system is useful for programmers writing consumer/producer style software and they want to do as little memory frobbing as possible.

If buf is already owned by someone else, the programmer should respect that and not change it. Instead, the programmer should make a copy of it, and work with a copy.

After a call to rbuf_own(3), buf cannot be rbuf_free(3)'ed, until after a call to rbuf_release(3). The programmer can find out if buf has been owned by calling rbuf_owned(3).

rbuf_copy_if_owned(3) is a convenience function that will copy an RBuf if it is already owned. This allows the consumer to know for certain that it will have a copy it can rbuf_own(3).

CONSUMER/PRODUCER EXAMPLE
This is the proper way to use the rbuf ownership system.

        void start (void)
        {
                producer ();
                finish ();
        }

        void producer (void)
        {
                RBuf * buf;

                /* We create a real rbuf here, but we could just as easily
                 * use rbuf_auto().  In our example, the buf will be owned
                 * in the consume function, and free below will be ignored.
                 * Had rbuf_auto() been used, the buf would have been
                 * owned (it is owned by the text segment so to speek), and
                 * a copy would have been made in the consume() function. */
                buf = rbuf_new_with_str ("Produced");
                consume (buf);

                /* We can blindly call free on the buf here because if it
                 * is owned, the call will be ignored, otherwise, it will
                 * really be free()'d */
                rbuf_free (buf);        /* Consumer might own buf. */

        }

        RBuf * saved = NULL;
        void consume (RBuf * buf)
        {
                /* Some made up logic to see if we need to keep a copy of this buf */
                if (keep_this_rbuf (buf))
                {
                        /* Now, if buf is owned by the calling function, we
                         * make a copy.  If it is not, we simply claim ownership
                         * of the buffer, and save it */
                        if (rbuf_owned (buf))   
                                buf = rbuf_new_with_rbuf (buf);
                        rbuf_own (buf);

                        saved = buf;            /* Save off buf. */
                }
        }

        void finish (void)
        {
                /* Use saved for stuff. */

                /* Do the cleanup.  rbuf_release() is required before rbuf_free(),
                 * as rbuf_free() is ignored for owned rbufs */
                rbuf_release (saved);
                rbuf_free (saved);
        }

RETURN VALUE

Calls to rbuf_own(3) and rbuf_release(3) don't return a value.

A call to rbuf_owned(3) returns TRUE if buf is owned because of a previous call to rbuf_own(3), or FALSE if there is no owner.

A call to rbuf_copy_if_owned(3) will return a pointer to buf if buf was unowned. If owned, a copy of buf will be created and returned.

ERRORS

Calls to rbuf_own(3), rbuf_release(3), and rbuf_owned(3) never fail.

MACRO

The rbuf ownership api calls are implemented using macros.

SEE ALSO