tor
master
|
Macros for C weak-handle implementation. More...
Go to the source code of this file.
Macros | |
#define | HANDLE_ENTRY(name, structname) struct name ## _handle_head_t *handle_head |
#define | HANDLE_DECL(name, structname, linkage) |
#define | HANDLE_IMPL(name, structname, linkage) |
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])
#define HANDLE_DECL | ( | name, | |
structname, | |||
linkage | |||
) |