Libevhtp 1.2.13
refcount.h
Go to the documentation of this file.
1#pragma once
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <stddef.h>
6#include <pthread.h>
7
8static void (*REF_free)(void *) = free;
9static void * (* REF_realloc)(void *, size_t) = realloc;
10static void * (* REF_malloc)(size_t) = malloc;
11
12struct refcount_ {
13 pthread_mutex_t mux;
14 unsigned int count;
15 char data[];
16};
17
18#define ref_upcast(DAT) \
19 (struct refcount_ *)((char *)(DAT - offsetof(struct refcount_, data)))
20
21#define ref_barrier(CODE) \
22 pthread_mutex_lock(&refc->mux); \
23 CODE \
24 pthread_mutex_unlock(&refc->mux)
25
26
27static inline void
28ref_init_functions(void *(*mallocf)(size_t),
29 void * (*callocf)(size_t, size_t),
30 void *(*reallocf)(void *, size_t),
31 void (*freef)(void *))
32{
33 (void)callocf;
34 REF_malloc = mallocf;
35 REF_realloc = reallocf;
36 REF_free = freef;
37}
38
39static unsigned int
40ref_inc(void * buf)
41{
42 struct refcount_ * refc = ref_upcast(buf);
43 unsigned int refs;
44
45 ref_barrier({ refs = ++refc->count; });
46
47 return refs;
48}
49
50static unsigned int
51ref_dec(void * buf)
52{
53 struct refcount_ * refc = ref_upcast(buf);
54 unsigned int refs;
55
56 ref_barrier({ refc->count -= 1; refs = refc->count; });
57
58 return refs;
59}
60
61static inline void *
62ref_malloc(size_t size)
63{
64 struct refcount_ * refc;
65 pthread_mutexattr_t attr;
66
67 refc = REF_malloc(sizeof(*refc) + size);
68 refc->count = 1;
69
70 pthread_mutexattr_init(&attr);
71 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
72 pthread_mutex_init(&refc->mux, &attr);
73
74 return refc->data;
75}
76
77static void
78ref_free(void * buf)
79{
80 struct refcount_ * refc = ref_upcast(buf);
81
83 if (--refc->count == 0)
84 {
85 pthread_mutex_unlock(&refc->mux);
86 pthread_mutex_destroy(&refc->mux);
87 return REF_free(refc);
88 }
89 });
90}
static void(* REF_free)(void *)
Definition: refcount.h:8
static void ref_init_functions(void *(*mallocf)(size_t), void *(*callocf)(size_t, size_t), void *(*reallocf)(void *, size_t), void(*freef)(void *))
Definition: refcount.h:28
#define ref_upcast(DAT)
Definition: refcount.h:18
static void * ref_malloc(size_t size)
Definition: refcount.h:62
static void *(* REF_realloc)(void *, size_t)
Definition: refcount.h:9
#define ref_barrier(CODE)
Definition: refcount.h:21
static void *(* REF_malloc)(size_t)
Definition: refcount.h:10
static unsigned int ref_inc(void *buf)
Definition: refcount.h:40
static void ref_free(void *buf)
Definition: refcount.h:78
static unsigned int ref_dec(void *buf)
Definition: refcount.h:51
pthread_mutex_t mux
Definition: refcount.h:13
unsigned int count
Definition: refcount.h:14
char data[]
Definition: refcount.h:15