Repository navigation
Expand file tree
/
Copy pathsignal.h
More file actions
98 lines (86 loc) · 2.74 KB
/
Copy pathsignal.h
File metadata and controls
98 lines (86 loc) · 2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*
* common/signal.h - Signal handling functions
*
* Copyright © 2009 Julien Danjou <julien@danjou.info>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef AWESOME_COMMON_SIGNAL
#define AWESOME_COMMON_SIGNAL
#include "common/array.h"
DO_ARRAY(const void *, cptr, DO_NOTHING)
typedef struct
{
unsigned long id;
cptr_array_t sigfuncs;
} signal_t;
static inline int
signal_cmp(const void *a, const void *b)
{
const signal_t *x = a, *y = b;
return x->id > y->id ? 1 : (x->id < y->id ? -1 : 0);
}
static inline void
signal_wipe(signal_t *sig)
{
cptr_array_wipe(&sig->sigfuncs);
}
DO_BARRAY(signal_t, signal, signal_wipe, signal_cmp)
static inline signal_t *
signal_array_getbyid(const signal_array_t *arr, unsigned long id)
{
return signal_array_lookup(arr, (signal_t) { .id = id });
}
/** Add a signal inside a signal array.
* You are in charge of reference counting.
* \param arr The signal array.
* \param name The signal name.
* \param ref The reference to add.
*/
static inline void
signal_add(signal_array_t *arr, const char *name, const void *ref)
{
unsigned long tok = a_strhash((const unsigned char *) name);
signal_t *sigfound = signal_array_getbyid(arr, tok);
if(sigfound)
cptr_array_append(&sigfound->sigfuncs, ref);
else
{
signal_t sig = { .id = tok };
cptr_array_append(&sig.sigfuncs, ref);
signal_array_insert(arr, sig);
}
}
/** Remove a signal inside a signal array.
* You are in charge of reference counting.
* \param arr The signal array.
* \param name The signal name.
* \param ref The reference to remove.
*/
static inline void
signal_remove(signal_array_t *arr, const char *name, const void *ref)
{
signal_t *sigfound = signal_array_getbyid(arr,
a_strhash((const unsigned char *) name));
if(sigfound)
{
cptr_array_find_and_remove(&sigfound->sigfuncs, ref);
/* No more function for the signal? Remove it. */
if(!sigfound->sigfuncs.len)
signal_array_remove(arr, sigfound);
}
}
#endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80