Lines 54-69
Link Here
|
54 |
* are using the static variables. |
54 |
* are using the static variables. |
55 |
*/ |
55 |
*/ |
56 |
|
56 |
|
57 |
static once_flag atexit_once_flag = ONCE_FLAG_INIT; |
|
|
58 |
static struct list_head queue_list = { |
57 |
static struct list_head queue_list = { |
59 |
.next = &queue_list, |
58 |
.next = &queue_list, |
60 |
.prev = &queue_list, |
59 |
.prev = &queue_list, |
61 |
}; |
60 |
}; |
62 |
static mtx_t exit_mutex; |
61 |
static mtx_t exit_mutex; |
63 |
|
62 |
|
64 |
static void |
63 |
__attribute__((constructor)) |
65 |
atexit_handler(void) |
64 |
static void initfn(void) |
66 |
{ |
65 |
{ |
|
|
66 |
mtx_init(&exit_mutex, mtx_plain); |
67 |
} |
68 |
|
69 |
__attribute__((destructor)) |
70 |
static void destructfn(void) |
71 |
{ |
67 |
struct util_queue *iter; |
72 |
struct util_queue *iter; |
68 |
|
73 |
|
69 |
mtx_lock(&exit_mutex); |
74 |
mtx_lock(&exit_mutex); |
Lines 75-91
Link Here
|
75 |
} |
80 |
} |
76 |
|
81 |
|
77 |
static void |
82 |
static void |
78 |
global_init(void) |
|
|
79 |
{ |
80 |
mtx_init(&exit_mutex, mtx_plain); |
81 |
atexit(atexit_handler); |
82 |
} |
83 |
|
84 |
static void |
85 |
add_to_atexit_list(struct util_queue *queue) |
83 |
add_to_atexit_list(struct util_queue *queue) |
86 |
{ |
84 |
{ |
87 |
call_once(&atexit_once_flag, global_init); |
|
|
88 |
|
89 |
mtx_lock(&exit_mutex); |
85 |
mtx_lock(&exit_mutex); |
90 |
list_add(&queue->head, &queue_list); |
86 |
list_add(&queue->head, &queue_list); |
91 |
mtx_unlock(&exit_mutex); |
87 |
mtx_unlock(&exit_mutex); |