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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
<table class="head">
<tr>
<td class="head-ltitle">EVENTHANDLER(9)</td>
<td class="head-vol">Kernel Developer's Manual</td>
<td class="head-rtitle">EVENTHANDLER(9)</td>
</tr>
</table>
<div class="manual-text">
<section class="Sh">
<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
<p class="Pp"><code class="Nm">EVENTHANDLER</code> —
<span class="Nd">kernel event handling functions</span></p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<p class="Pp"><code class="In">#include
<<a class="In">sys/eventhandler.h</a>></code></p>
<p class="Pp"><code class="Fn">EVENTHANDLER_DECLARE</code>(<var class="Fa" style="white-space: nowrap;">name</var>,
<var class="Fa" style="white-space: nowrap;">type</var>);</p>
<p class="Pp"><code class="Fn">EVENTHANDLER_DEFINE</code>(<var class="Fa" style="white-space: nowrap;">name</var>,
<var class="Fa" style="white-space: nowrap;">func</var>,
<var class="Fa" style="white-space: nowrap;">arg</var>,
<var class="Fa" style="white-space: nowrap;">priority</var>);</p>
<p class="Pp"><code class="Fn">EVENTHANDLER_INVOKE</code>(<var class="Fa" style="white-space: nowrap;">name</var>,
<var class="Fa" style="white-space: nowrap;">...</var>);</p>
<p class="Pp"><var class="Ft">eventhandler_tag</var>
<br/>
<code class="Fn">EVENTHANDLER_REGISTER</code>(<var class="Fa" style="white-space: nowrap;">name</var>,
<var class="Fa" style="white-space: nowrap;">func</var>,
<var class="Fa" style="white-space: nowrap;">arg</var>,
<var class="Fa" style="white-space: nowrap;">priority</var>);</p>
<p class="Pp"><code class="Fn">EVENTHANDLER_DEREGISTER</code>(<var class="Fa" style="white-space: nowrap;">name</var>,
<var class="Fa" style="white-space: nowrap;">tag</var>);</p>
<p class="Pp"><code class="Fn">EVENTHANDLER_DEREGISTER_NOWAIT</code>(<var class="Fa" style="white-space: nowrap;">name</var>,
<var class="Fa" style="white-space: nowrap;">tag</var>);</p>
<p class="Pp"><code class="Fn">EVENTHANDLER_LIST_DECLARE</code>(<var class="Fa" style="white-space: nowrap;">name</var>);</p>
<p class="Pp"><code class="Fn">EVENTHANDLER_LIST_DEFINE</code>(<var class="Fa" style="white-space: nowrap;">name</var>);</p>
<p class="Pp"><code class="Fn">EVENTHANDLER_DIRECT_INVOKE</code>(<var class="Fa" style="white-space: nowrap;">name</var>);</p>
<p class="Pp"><var class="Ft">eventhandler_tag</var>
<br/>
<code class="Fn">eventhandler_register</code>(<var class="Fa">struct
eventhandler_list *list</var>, <var class="Fa">const char *name</var>,
<var class="Fa">void *func</var>, <var class="Fa">void *arg</var>,
<var class="Fa">int priority</var>);</p>
<p class="Pp"><var class="Ft">void</var>
<br/>
<code class="Fn">eventhandler_deregister</code>(<var class="Fa">struct
eventhandler_list *list</var>, <var class="Fa">eventhandler_tag
tag</var>);</p>
<p class="Pp"><var class="Ft">void</var>
<br/>
<code class="Fn">eventhandler_deregister_nowait</code>(<var class="Fa">struct
eventhandler_list *list</var>, <var class="Fa">eventhandler_tag
tag</var>);</p>
<p class="Pp"><var class="Ft">struct eventhandler_list *</var>
<br/>
<code class="Fn">eventhandler_find_list</code>(<var class="Fa" style="white-space: nowrap;">const
char *name</var>);</p>
<p class="Pp"><var class="Ft">void</var>
<br/>
<code class="Fn">eventhandler_prune_list</code>(<var class="Fa" style="white-space: nowrap;">struct
eventhandler_list *list</var>);</p>
</section>
<section class="Sh">
<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
<p class="Pp">The <code class="Nm">EVENTHANDLER</code> mechanism provides a way
for kernel subsystems to register interest in kernel events and have their
callback functions invoked when these events occur.</p>
<p class="Pp">Callback functions are invoked in order of priority. The relative
priority of each callback among other callbacks associated with an event is
given by argument <var class="Fa">priority</var>, which is an integer
ranging from <code class="Dv">EVENTHANDLER_PRI_FIRST</code> (highest
priority), to <code class="Dv">EVENTHANDLER_PRI_LAST</code> (lowest
priority). The symbol <code class="Dv">EVENTHANDLER_PRI_ANY</code> may be
used if the handler does not have a specific priority associated with
it.</p>
<p class="Pp" id="EVENTHANDLER_LIST_DEFINE">The normal way to use this subsystem
is via the macro interface. For events that are high frequency it is
suggested that you additionally use
<a class="permalink" href="#EVENTHANDLER_LIST_DEFINE"><code class="Fn">EVENTHANDLER_LIST_DEFINE</code></a>()
so that the event handlers can be invoked directly using
<a class="permalink" href="#EVENTHANDLER_DIRECT_INVOKE"><code class="Fn" id="EVENTHANDLER_DIRECT_INVOKE">EVENTHANDLER_DIRECT_INVOKE</code></a>()
(see below). This saves the invoker from having to do a locked traversal of
a global list of event handler lists.</p>
<dl class="Bl-tag">
<dt id="EVENTHANDLER_DECLARE"><a class="permalink" href="#EVENTHANDLER_DECLARE"><code class="Fn">EVENTHANDLER_DECLARE</code></a>()</dt>
<dd>This macro declares an event handler named by argument
<var class="Fa">name</var> with callback functions of type
<var class="Fa">type</var>.</dd>
<dt id="EVENTHANDLER_DEFINE"><a class="permalink" href="#EVENTHANDLER_DEFINE"><code class="Fn">EVENTHANDLER_DEFINE</code></a>()</dt>
<dd>This macro uses <a class="Xr">SYSINIT(9)</a> to register a callback
function <var class="Fa">func</var> with event handler
<var class="Fa">name</var>. When invoked, function
<var class="Fa">func</var> will be invoked with argument
<var class="Fa">arg</var> as its first parameter along with any additional
parameters passed in via macro
<a class="permalink" href="#EVENTHANDLER_INVOKE"><code class="Fn" id="EVENTHANDLER_INVOKE">EVENTHANDLER_INVOKE</code></a>()
(see below).</dd>
<dt id="EVENTHANDLER_REGISTER"><a class="permalink" href="#EVENTHANDLER_REGISTER"><code class="Fn">EVENTHANDLER_REGISTER</code></a>()</dt>
<dd>This macro registers a callback function <var class="Fa">func</var> with
event handler <var class="Fa">name</var>. When invoked, function
<var class="Fa">func</var> will be invoked with argument
<var class="Fa">arg</var> as its first parameter along with any additional
parameters passed in via macro
<code class="Fn">EVENTHANDLER_INVOKE</code>() (see below).
<code class="Fn">EVENTHANDLER_REGISTER</code>() returns a cookie of type
<var class="Vt">eventhandler_tag</var>.</dd>
<dt id="EVENTHANDLER_DEREGISTER"><a class="permalink" href="#EVENTHANDLER_DEREGISTER"><code class="Fn">EVENTHANDLER_DEREGISTER</code></a>()</dt>
<dd>This macro removes a previously registered callback associated with tag
<var class="Fa">tag</var> from the event handler named by argument
<var class="Fa">name</var>. It waits until no threads are running handlers
for this event before returning, making it safe to unload a module
immediately upon return from this function.</dd>
<dt id="EVENTHANDLER_DEREGISTER_NOWAIT"><a class="permalink" href="#EVENTHANDLER_DEREGISTER_NOWAIT"><code class="Fn">EVENTHANDLER_DEREGISTER_NOWAIT</code></a>()</dt>
<dd>This macro removes a previously registered callback associated with tag
<var class="Fa">tag</var> from the event handler named by argument
<var class="Fa">name</var>. Upon return, one or more threads could still
be running the removed function(s), but no new calls will be made. To
remove a handler function from within that function, use this version of
deregister, to avoid a deadlock.</dd>
<dt><code class="Fn">EVENTHANDLER_INVOKE</code>()</dt>
<dd>This macro is used to invoke all the callbacks associated with event
handler <var class="Fa">name</var>. This macro is a variadic one.
Additional arguments to the macro after the <var class="Fa">name</var>
parameter are passed as the second and subsequent arguments to each
registered callback function.</dd>
<dt><code class="Fn">EVENTHANDLER_LIST_DEFINE</code>()</dt>
<dd>This macro defines a reference to an event handler list named by argument
<var class="Fa">name</var>. It uses <a class="Xr">SYSINIT(9)</a> to
initialize the reference and the eventhandler list.</dd>
<dt id="EVENTHANDLER_LIST_DECLARE"><a class="permalink" href="#EVENTHANDLER_LIST_DECLARE"><code class="Fn">EVENTHANDLER_LIST_DECLARE</code></a>()</dt>
<dd>This macro declares an event handler list named by argument
<var class="Fa">name</var>. This is only needed for users of
<code class="Fn">EVENTHANDLER_DIRECT_INVOKE</code>() which are not in the
same compilation unit of that list's definition.</dd>
<dt><code class="Fn">EVENTHANDLER_DIRECT_INVOKE</code>()</dt>
<dd>This macro invokes the event handlers registered for the list named by
argument <var class="Fa">name</var>. This macro can only be used if the
list was defined with <code class="Fn">EVENTHANDLER_LIST_DEFINE</code>().
The macro is variadic with the same semantics as
<code class="Fn">EVENTHANDLER_INVOKE</code>().</dd>
</dl>
<p class="Pp">The macros are implemented using the following functions:</p>
<dl class="Bl-tag">
<dt id="eventhandler_register"><a class="permalink" href="#eventhandler_register"><code class="Fn">eventhandler_register</code></a>()</dt>
<dd>The <code class="Fn">eventhandler_register</code>() function is used to
register a callback with a given event. The arguments expected by this
function are:
<dl class="Bl-tag">
<dt><var class="Fa">list</var></dt>
<dd>A pointer to an existing event handler list, or
<code class="Dv">NULL</code>. If <var class="Fa">list</var> is
<code class="Dv">NULL</code>, the event handler list corresponding to
argument <var class="Fa">name</var> is used.</dd>
<dt><var class="Fa">name</var></dt>
<dd>The name of the event handler list.</dd>
<dt><var class="Fa">func</var></dt>
<dd>A pointer to a callback function. Argument <var class="Fa">arg</var>
is passed to the callback function <var class="Fa">func</var> as its
first argument when it is invoked.</dd>
<dt><var class="Fa">priority</var></dt>
<dd>The relative priority of this callback among all the callbacks
registered for this event. Valid values are those in the range
<code class="Dv">EVENTHANDLER_PRI_FIRST</code> to
<code class="Dv">EVENTHANDLER_PRI_LAST</code>.</dd>
</dl>
<p class="Pp" id="eventhandler_register~2">The
<a class="permalink" href="#eventhandler_register~2"><code class="Fn">eventhandler_register</code></a>()
function returns a <var class="Fa">tag</var> that can later be used with
<a class="permalink" href="#eventhandler_deregister"><code class="Fn" id="eventhandler_deregister">eventhandler_deregister</code></a>()
to remove the particular callback function.</p>
</dd>
<dt><code class="Fn">eventhandler_deregister</code>()</dt>
<dd>The <code class="Fn">eventhandler_deregister</code>() function removes the
callback associated with tag <var class="Fa">tag</var> from the event
handler list pointed to by <var class="Fa">list</var>. If
<var class="Fa">tag</var> is <var class="Va">NULL</var>, all callback
functions for the event are removed. This function will not return until
all threads have exited from the removed handler callback function(s).
This function is not safe to call from inside an event handler
callback.</dd>
<dt id="eventhandler_deregister_nowait"><a class="permalink" href="#eventhandler_deregister_nowait"><code class="Fn">eventhandler_deregister_nowait</code></a>()</dt>
<dd>The <code class="Fn">eventhandler_deregister</code>() function removes the
callback associated with tag <var class="Fa">tag</var> from the event
handler list pointed to by <var class="Fa">list</var>. This function is
safe to call from inside an event handler callback.</dd>
<dt id="eventhandler_find_list"><a class="permalink" href="#eventhandler_find_list"><code class="Fn">eventhandler_find_list</code></a>()</dt>
<dd>The <code class="Fn">eventhandler_find_list</code>() function returns a
pointer to event handler list structure corresponding to event
<var class="Fa">name</var>.</dd>
<dt id="eventhandler_prune_list"><a class="permalink" href="#eventhandler_prune_list"><code class="Fn">eventhandler_prune_list</code></a>()</dt>
<dd>The <code class="Fn">eventhandler_prune_list</code>() function removes all
deregistered callbacks from the event list
<var class="Fa">list</var>.</dd>
</dl>
</section>
<section class="Sh">
<h1 class="Sh" id="RETURN_VALUES"><a class="permalink" href="#RETURN_VALUES">RETURN
VALUES</a></h1>
<p class="Pp">The macro <code class="Fn">EVENTHANDLER_REGISTER</code>() and
function <code class="Fn">eventhandler_register</code>() return a cookie of
type <var class="Vt">eventhandler_tag</var>, which may be used in a
subsequent call to <code class="Fn">EVENTHANDLER_DEREGISTER</code>() or
<code class="Fn">eventhandler_deregister</code>().</p>
<p class="Pp">The <code class="Fn">eventhandler_find_list</code>() function
returns a pointer to an event handler list corresponding to parameter
<var class="Fa">name</var>, or <code class="Dv">NULL</code> if no such list
was found.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
<p class="Pp">The <code class="Nm">EVENTHANDLER</code> facility first appeared
in <span class="Ux">FreeBSD 4.0</span>.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
<p class="Pp">This manual page was written by <span class="An">Joseph
Koshy</span>
<<a class="Mt" href="mailto:jkoshy@FreeBSD.org">jkoshy@FreeBSD.org</a>>
and
<br/>
<span class="An">Matt Joras</span>
<<a class="Mt" href="mailto:mjoras@FreeBSD.org">mjoras@FreeBSD.org</a>>.</p>
</section>
</div>
<table class="foot">
<tr>
<td class="foot-date">January 31, 2025</td>
<td class="foot-os">FreeBSD 15.0</td>
</tr>
</table>
|