]> git.ozlabs.org Git - ccan/blobdiff - ccan/talloc_link/_info
talloc_link; a replacement for talloc's references.
[ccan] / ccan / talloc_link / _info
diff --git a/ccan/talloc_link/_info b/ccan/talloc_link/_info
new file mode 100644 (file)
index 0000000..fe66c24
--- /dev/null
@@ -0,0 +1,146 @@
+#include <stdio.h>
+#include <string.h>
+#include "config.h"
+
+/**
+ * talloc_link - link helper for talloc
+ *
+ * Talloc references can be confusing and buggy.  In the cases where an object
+ * needs multiple parents, all parents need to be aware of the situation; thus
+ * talloc_link is a helper where all "parents" talloc_link an object they
+ * agree to share ownership of.
+ *
+ * Example:
+ *     // Silly program which keeps a cache of uppercased strings.
+ *     // The cache wants to keep strings around even after they may have
+ *     // been "freed" by the caller.
+ *     #include <stdio.h>
+ *     #include <err.h>
+ *     #include <string.h>
+ *     #include <ctype.h>
+ *     #include <ccan/talloc/talloc.h>
+ *     #include <ccan/talloc_link/talloc_link.h>
+ *
+ *     struct upcache {
+ *             const char *str;
+ *             const char *upstr;
+ *     };
+ *
+ *     static struct upcache *cache;
+ *     static unsigned int cache_hits = 0;
+ *     #define CACHE_SIZE 4
+ *     void init_upcase(void)
+ *     {
+ *             cache = talloc_zero_array(NULL, struct upcache, CACHE_SIZE);
+ *     }
+ *
+ *     static struct upcache *lookup_upcase(const char *str)
+ *     {
+ *             unsigned int i;
+ *             for (i = 0; i < CACHE_SIZE; i++)
+ *                     if (cache[i].str && !strcmp(cache[i].str, str)) {
+ *                             cache_hits++;
+ *                             return &cache[i];
+ *                     }
+ *             return NULL;
+ *     }
+ *
+ *     static struct upcache *new_upcase(const char *str)
+ *     {
+ *             unsigned int i;
+ *             char *upstr;
+ *
+ *             upstr = talloc_linked(cache, talloc_strdup(NULL, str));
+ *             if (!upstr)
+ *                     return NULL;
+ *
+ *             i = random() % CACHE_SIZE;
+ *
+ *             // Throw out old: works fine if cache[i].upstr is NULL.
+ *             talloc_delink(cache, cache[i].upstr);
+ *
+ *             // Replace with new.
+ *             cache[i].str = str;
+ *             cache[i].upstr = upstr;
+ *             while (*upstr) {
+ *                     *upstr = toupper(*upstr);
+ *                     upstr++;
+ *             }
+ *             return &cache[i];
+ *     }
+ *
+ *     // If you want to keep the result, talloc_link it.
+ *     const char *get_upcase(const char *str)
+ *     {
+ *             struct upcache *uc = lookup_upcase(str);
+ *             if (!uc)
+ *                     uc = new_upcase(str);
+ *             if (!uc)
+ *                     return NULL;
+ *             return uc->upstr;
+ *     }
+ *
+ *     void exit_upcase(void)
+ *     {
+ *             talloc_free(cache);
+ *             printf("Cache hits: %u\n", cache_hits);
+ *     }
+ *
+ *     int main(int argc, char *argv[])
+ *     {
+ *             unsigned int i;
+ *             const char **values;
+ *
+ *             // Will dump any memory leaks to stderr on exit.
+ *             talloc_enable_leak_report();
+ *
+ *             // Initialize cache.
+ *             init_upcase();
+ *
+ *             // Throw values in.
+ *             values = talloc_array(NULL, const char *, argc);
+ *             for (i = 1; i < argc; i++) {
+ *                     values[i-1] = talloc_link(values, get_upcase(argv[i]));
+ *                     if (!values[i-1])
+ *                             err(1, "Out of memory");
+ *             }
+ *             // This will free all the values, but cache will still work.
+ *             talloc_free(values);
+ *
+ *             // Repeat!
+ *             values = talloc_array(NULL, const char *, argc);
+ *             for (i = 1; i < argc; i++) {
+ *                     values[i-1] = talloc_link(values, get_upcase(argv[i]));
+ *                     if (!values[i-1])
+ *                             err(1, "Out of memory");
+ *             }
+ *
+ *             // This will remove cache links, but we still have a link.
+ *             exit_upcase();
+ *
+ *             // Show values, so we output something.
+ *             for (i = 0; i < argc - 1; i++)
+ *                     printf("%s ", values[i]);
+ *             printf("\n");
+ *
+ *             // This will finally free the upcase strings (last link).
+ *             talloc_free(values);
+ *
+ *             return 0;
+ *     }
+ *
+ * Licence: GPL (2 or any later version)
+ */
+int main(int argc, char *argv[])
+{
+       if (argc != 2)
+               return 1;
+
+       if (strcmp(argv[1], "depends") == 0) {
+               printf("ccan/talloc\n");
+               printf("ccan/list\n");
+               return 0;
+       }
+
+       return 1;
+}