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 
8 static void (*REF_free)(void *) = free;
9 static void * (* REF_realloc)(void *, size_t) = realloc;
10 static void * (* REF_malloc)(size_t) = malloc;
11 
12 struct 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 
27 static inline void
28 ref_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 
39 static unsigned int
40 ref_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 
50 static unsigned int
51 ref_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 
61 static inline void *
62 ref_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 
77 static void
78 ref_free(void * buf)
79 {
80  struct refcount_ * refc = ref_upcast(buf);
81 
82  ref_barrier({
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 }
refcount_::count
unsigned int count
Definition: refcount.h:14
REF_realloc
static void *(* REF_realloc)(void *, size_t)
Definition: refcount.h:9
REF_free
static void(* REF_free)(void *)
Definition: refcount.h:8
ref_barrier
#define ref_barrier(CODE)
Definition: refcount.h:21
ref_init_functions
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
refcount_
Definition: refcount.h:12
refcount_::data
char data[]
Definition: refcount.h:15
ref_free
static void ref_free(void *buf)
Definition: refcount.h:78
ref_inc
static unsigned int ref_inc(void *buf)
Definition: refcount.h:40
ref_dec
static unsigned int ref_dec(void *buf)
Definition: refcount.h:51
ref_upcast
#define ref_upcast(DAT)
Definition: refcount.h:18
refcount_::mux
pthread_mutex_t mux
Definition: refcount.h:13
REF_malloc
static void *(* REF_malloc)(size_t)
Definition: refcount.h:10
ref_malloc
static void * ref_malloc(size_t size)
Definition: refcount.h:62