diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-07-05 14:45:34 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-07-05 14:45:34 -0400 |
commit | 0e4b1781f4f0135c925cd728a09cca7d7959b961 (patch) | |
tree | 885d1bed56b9ccc668fa5d1c7f8108a9117c38d4 /src/common | |
parent | 3d610363eff2fe70d3775a66a97f844956480141 (diff) | |
download | tor-0e4b1781f4f0135c925cd728a09cca7d7959b961.tar.gz tor-0e4b1781f4f0135c925cd728a09cca7d7959b961.zip |
Move handles.h to src/lib/container
There might be a better place for it in the long run, but this is
the best we can think of for now.
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/handles.h | 153 | ||||
-rw-r--r-- | src/common/include.am | 1 |
2 files changed, 0 insertions, 154 deletions
diff --git a/src/common/handles.h b/src/common/handles.h deleted file mode 100644 index 21ec0dfeec..0000000000 --- a/src/common/handles.h +++ /dev/null @@ -1,153 +0,0 @@ -/* Copyright (c) 2016-2018, The Tor Project, Inc. */ -/* See LICENSE for licensing information */ - -/** - * \file handles.h - * \brief Macros for C weak-handle implementation. - * - * A 'handle' is a pointer to an object that is allowed to go away while - * the handle stays alive. When you dereference the handle, you might get - * the object, or you might get "NULL". - * - * Use this pattern when an object has a single obvious lifespan, so you don't - * want to use reference counting, but when other objects might need to refer - * to the first object without caring about its lifetime. - * - * To enable a type to have handles, add a HANDLE_ENTRY() field in its - * definition, as in: - * - * struct walrus { - * HANDLE_ENTRY(wlr, walrus); - * // ... - * }; - * - * And invoke HANDLE_DECL(wlr, walrus, [static]) to declare the handle - * manipulation functions (typically in a header): - * - * // opaque handle to walrus. - * typedef struct wlr_handle_t wlr_handle_t; - * - * // make a new handle - * struct wlr_handle_t *wlr_handle_new(struct walrus *); - * - * // release a handle - * void wlr_handle_free(wlr_handle_t *); - * - * // return the pointed-to walrus, or NULL. - * struct walrus *wlr_handle_get(wlr_handle_t *). - * - * // call this function when you're about to free the walrus; - * // it invalidates all handles. (IF YOU DON'T, YOU WILL HAVE - * // DANGLING REFERENCES) - * void wlr_handles_clear(struct walrus *); - * - * Finally, use HANDLE_IMPL() to define the above functions in some - * appropriate C file: HANDLE_IMPL(wlr, walrus, [static]) - * - **/ - -#ifndef TOR_HANDLE_H -#define TOR_HANDLE_H - -#include "orconfig.h" - -#include "lib/log/util_bug.h" -#include "lib/malloc/util_malloc.h" - -#define HANDLE_ENTRY(name, structname) \ - struct name ## _handle_head_t *handle_head - -#define HANDLE_DECL(name, structname, linkage) \ - typedef struct name ## _handle_t name ## _handle_t; \ - linkage name ## _handle_t *name ## _handle_new(struct structname *object); \ - linkage void name ## _handle_free_(name ## _handle_t *); \ - linkage struct structname *name ## _handle_get(name ## _handle_t *); \ - linkage void name ## _handles_clear(struct structname *object); - -/* - * Implementation notes: there are lots of possible implementations here. We - * could keep a linked list of handles, each with a backpointer to the object, - * and set all of their backpointers to NULL when the object is freed. Or we - * could have the clear function invalidate the object, but not actually let - * the object get freed until the all the handles went away. We could even - * have a hash-table mapping unique identifiers to objects, and have each - * handle be a copy of the unique identifier. (We'll want to build that last - * one eventually if we want cross-process handles.) - * - * But instead we're opting for a single independent 'head' that knows how - * many handles there are, and where the object is (or isn't). This makes - * all of our functions O(1), and most as fast as a single pointer access. - * - * The handles themselves are opaque structures holding a pointer to the head. - * We could instead have each foo_handle_t* be identical to foo_handle_head_t - * *, and save some allocations ... but doing so would make handle leaks - * harder to debug. As it stands, every handle leak is a memory leak, and - * existing memory debugging tools should help with those. We can revisit - * this decision if handles are too slow. - */ - -#define HANDLE_IMPL(name, structname, linkage) \ - /* The 'head' object for a handle-accessible type. This object */ \ - /* persists for as long as the object, or any handles, exist. */ \ - typedef struct name ## _handle_head_t { \ - struct structname *object; /* pointed-to object, or NULL */ \ - unsigned int references; /* number of existing handles */ \ - } name ## _handle_head_t; \ - \ - struct name ## _handle_t { \ - struct name ## _handle_head_t *head; /* reference to the 'head'. */ \ - }; \ - \ - linkage struct name ## _handle_t * \ - name ## _handle_new(struct structname *object) \ - { \ - tor_assert(object); \ - name ## _handle_head_t *head = object->handle_head; \ - if (PREDICT_UNLIKELY(head == NULL)) { \ - head = object->handle_head = tor_malloc_zero(sizeof(*head)); \ - head->object = object; \ - } \ - name ## _handle_t *new_ref = tor_malloc_zero(sizeof(*new_ref)); \ - new_ref->head = head; \ - ++head->references; \ - return new_ref; \ - } \ - \ - linkage void \ - name ## _handle_free_(struct name ## _handle_t *ref) \ - { \ - if (! ref) return; \ - name ## _handle_head_t *head = ref->head; \ - tor_assert(head); \ - --head->references; \ - tor_free(ref); \ - if (head->object == NULL && head->references == 0) { \ - tor_free(head); \ - return; \ - } \ - } \ - \ - linkage struct structname * \ - name ## _handle_get(struct name ## _handle_t *ref) \ - { \ - tor_assert(ref); \ - name ## _handle_head_t *head = ref->head; \ - tor_assert(head); \ - return head->object; \ - } \ - \ - linkage void \ - name ## _handles_clear(struct structname *object) \ - { \ - tor_assert(object); \ - name ## _handle_head_t *head = object->handle_head; \ - if (! head) \ - return; \ - object->handle_head = NULL; \ - head->object = NULL; \ - if (head->references == 0) { \ - tor_free(head); \ - } \ - } - -#endif /* !defined(TOR_HANDLE_H) */ diff --git a/src/common/include.am b/src/common/include.am index 7427c69445..d352a46de9 100644 --- a/src/common/include.am +++ b/src/common/include.am @@ -51,7 +51,6 @@ src_common_libor_event_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) COMMONHEADERS = \ src/common/address_set.h \ src/common/compat_libevent.h \ - src/common/handles.h \ src/common/procmon.h \ src/common/socks5_status.h \ src/common/timers.h \ |