Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150247102
D12561.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D12561.diff
View Options
Index: head/share/man/man9/EVENTHANDLER.9
===================================================================
--- head/share/man/man9/EVENTHANDLER.9
+++ head/share/man/man9/EVENTHANDLER.9
@@ -23,7 +23,7 @@
.\" SUCH DAMAGE.
.\" $FreeBSD$
.\"
-.Dd March 27, 2017
+.Dd October 1, 2017
.Dt EVENTHANDLER 9
.Os
.Sh NAME
@@ -37,6 +37,7 @@
.Ft eventhandler_tag
.Fn EVENTHANDLER_REGISTER name func arg priority
.Fn EVENTHANDLER_DEREGISTER name tag
+.Fn EVENTHANDLER_DEREGISTER_NOWAIT name tag
.Ft eventhandler_tag
.Fo eventhandler_register
.Fa "struct eventhandler_list *list"
@@ -50,6 +51,11 @@
.Fa "struct eventhandler_list *list"
.Fa "eventhandler_tag tag"
.Fc
+.Ft void
+.Fo eventhandler_deregister_nowait
+.Fa "struct eventhandler_list *list"
+.Fa "eventhandler_tag tag"
+.Fc
.Ft "struct eventhandler_list *"
.Fn eventhandler_find_list "const char *name"
.Ft void
@@ -121,6 +127,18 @@
.Fa tag
from the event handler named by argument
.Fa name .
+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.
+.It Fn EVENTHANDLER_DEREGISTER_NOWAIT
+This macro removes a previously registered callback associated with tag
+.Fa tag
+from the event handler named by argument
+.Fa name .
+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.
.It Fn EVENTHANDLER_INVOKE
This macro is used to invoke all the callbacks associated with event
handler
@@ -176,6 +194,21 @@
.Fn eventhandler_deregister
to remove the particular callback function.
.It Fn eventhandler_deregister
+The
+.Fn eventhandler_deregister
+function removes the callback associated with tag
+.Fa tag
+from the event handler list pointed to by
+.Fa list .
+If
+.Fa tag
+is
+.Va NULL ,
+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.
+.It Fn eventhandler_deregister_nowait
The
.Fn eventhandler_deregister
function removes the callback associated with tag
Index: head/sys/kern/subr_eventhandler.c
===================================================================
--- head/sys/kern/subr_eventhandler.c
+++ head/sys/kern/subr_eventhandler.c
@@ -180,8 +180,9 @@
}
#endif
-void
-eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
+static void
+_eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag,
+ bool wait)
{
struct eventhandler_entry *ep = tag;
@@ -215,9 +216,24 @@
ep->ee_priority = EHE_DEAD_PRIORITY;
}
}
- while (list->el_runcount > 0)
+ while (wait && list->el_runcount > 0)
mtx_sleep(list, &list->el_lock, 0, "evhrm", 0);
EHL_UNLOCK(list);
+}
+
+void
+eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
+{
+
+ _eventhandler_deregister(list, tag, true);
+}
+
+void
+eventhandler_deregister_nowait(struct eventhandler_list *list,
+ eventhandler_tag tag)
+{
+
+ _eventhandler_deregister(list, tag, false);
}
/*
Index: head/sys/sys/eventhandler.h
===================================================================
--- head/sys/sys/eventhandler.h
+++ head/sys/sys/eventhandler.h
@@ -141,11 +141,20 @@
if ((_el = eventhandler_find_list(#name)) != NULL) \
eventhandler_deregister(_el, tag); \
} while(0)
-
+#define EVENTHANDLER_DEREGISTER_NOWAIT(name, tag) \
+do { \
+ struct eventhandler_list *_el; \
+ \
+ if ((_el = eventhandler_find_list(#name)) != NULL) \
+ eventhandler_deregister_nowait(_el, tag); \
+} while(0)
+
eventhandler_tag eventhandler_register(struct eventhandler_list *list,
const char *name, void *func, void *arg, int priority);
void eventhandler_deregister(struct eventhandler_list *list,
+ eventhandler_tag tag);
+void eventhandler_deregister_nowait(struct eventhandler_list *list,
eventhandler_tag tag);
struct eventhandler_list *eventhandler_find_list(const char *name);
void eventhandler_prune_list(struct eventhandler_list *list);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Mar 31, 2:41 PM (20 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30638846
Default Alt Text
D12561.diff (4 KB)
Attached To
Mode
D12561: Restore the ability to deregister an eventhandler callback from within the callback.
Attached
Detach File
Event Timeline
Log In to Comment