summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Alexander Lehmann <libev@schmorp.de>2020-01-22 02:00:13 +0000
committerMarc Alexander Lehmann <libev@schmorp.de>2020-01-22 02:00:13 +0000
commit5266c2d69c7c51b756b9c3fd12df415dd2f2ead7 (patch)
tree74f73256ec06dacad9bf7044edde48f58b628f7e
parent0adc8e592f7512926996e885176a1bef6a59d938 (diff)
downloadlibev-5266c2d69c7c51b756b9c3fd12df415dd2f2ead7.tar.gz
libev-5266c2d69c7c51b756b9c3fd12df415dd2f2ead7.zip
*** empty log message ***
-rw-r--r--Changes7
-rw-r--r--ev.338
-rw-r--r--ev.h3
-rw-r--r--ev.pod11
4 files changed, 40 insertions, 19 deletions
diff --git a/Changes b/Changes
index 394420a..3dd469f 100644
--- a/Changes
+++ b/Changes
@@ -5,12 +5,15 @@ TODO: ^ maybe just increase it when timerfd, modern linux only thing that counts
TODO: document EV_TSTAMP_T
TODO: for next ABI/API change, consider moving EV__IOFDSSET into io->fd instead and provide a getter.
-TODO: add ev_io_set_events, or ev_io_modify, or ev_io_change, or..., without IOFDSET
-TODO: fix documentation of read-only] [read-write] and so on
TODO: maybe allow events = 0 for io watchers
- the 4.31 timerfd code wrongly changes the priority of the signal
fd watcher, which is usually harmless unless signal fds are
also used (found via cpan tester service).
+ - the documentation wrongly claimed that user may modify fd and events
+ members in io watchers when the wqatcher was stopped
+ (found by b_jonas).
+ - new ev_io_modify mutator which changes only the events member,
+ which cna be faster.
- do not wake up every minute when timerfd is used to detect timejumps.
- support a lot more "uncommon" compile time configurations,
such as ev_embed enabled but ev_timer disabled.
diff --git a/ev.3 b/ev.3
index 3e51390..3aae0cd 100644
--- a/ev.3
+++ b/ev.3
@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "LIBEV 3"
-.TH LIBEV 3 "2019-12-21" "libev-4.31" "libev - high performance full featured event loop"
+.TH LIBEV 3 "2020-01-22" "libev-4.31" "libev - high performance full featured event loop"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@@ -1769,14 +1769,17 @@ This section describes each watcher in detail, but will not repeat
information given in the last section. Any initialisation/set macros,
functions and members specific to the watcher type are explained.
.PP
-Members are additionally marked with either \fI[read\-only]\fR, meaning that,
-while the watcher is active, you can look at the member and expect some
-sensible content, but you must not modify it (you can modify it while the
-watcher is stopped to your hearts content), or \fI[read\-write]\fR, which
+Most members are additionally marked with either \fI[read\-only]\fR, meaning
+that, while the watcher is active, you can look at the member and expect
+some sensible content, but you must not modify it (you can modify it while
+the watcher is stopped to your hearts content), or \fI[read\-write]\fR, which
means you can expect it to have some sensible content while the watcher
is active, but you can also modify it. Modifying it may not do something
sensible or take immediate effect (or do anything at all), but libev will
not crash or malfunction in any way.
+.PP
+In any case, the documentation for each member will explain what the
+effects are, and if there are any additional access restrictions.
.ie n .SS """ev_io"" \- is this file descriptor readable or writable?"
.el .SS "\f(CWev_io\fP \- is this file descriptor readable or writable?"
.IX Subsection "ev_io - is this file descriptor readable or writable?"
@@ -1954,12 +1957,25 @@ opportunity for a DoS attack.
Configures an \f(CW\*(C`ev_io\*(C'\fR watcher. The \f(CW\*(C`fd\*(C'\fR is the file descriptor to
receive events for and \f(CW\*(C`events\*(C'\fR is either \f(CW\*(C`EV_READ\*(C'\fR, \f(CW\*(C`EV_WRITE\*(C'\fR or
\&\f(CW\*(C`EV_READ | EV_WRITE\*(C'\fR, to express the desire to receive the given events.
-.IP "int fd [read\-only]" 4
-.IX Item "int fd [read-only]"
-The file descriptor being watched.
-.IP "int events [read\-only]" 4
-.IX Item "int events [read-only]"
-The events being watched.
+.IP "ev_io_modify (ev_io *, int events)" 4
+.IX Item "ev_io_modify (ev_io *, int events)"
+Similar to \f(CW\*(C`ev_io_set\*(C'\fR, but only changes the event mask. Using this might
+be faster with some backends, as libev can assume that the \f(CW\*(C`fd\*(C'\fR still
+refers to the same underlying file description, something it cannot do
+when using \f(CW\*(C`ev_io_set\*(C'\fR.
+.IP "int fd [no\-modify]" 4
+.IX Item "int fd [no-modify]"
+The file descriptor being watched. While it can be read at any time, you
+must not modify this member even when the watcher is stopped \- always use
+\&\f(CW\*(C`ev_io_set\*(C'\fR for that.
+.IP "int events [no\-modify]" 4
+.IX Item "int events [no-modify]"
+The set of events being watched, among other flags. This field is a
+bit set \- to test for \f(CW\*(C`EV_READ\*(C'\fR, use \f(CW\*(C`w\->events & EV_READ\*(C'\fR, and
+similarly for \f(CW\*(C`EV_WRITE\*(C'\fR.
+.Sp
+As with \f(CW\*(C`fd\*(C'\fR, you must not modify this member even when the watcher is
+stopped, always use \f(CW\*(C`ev_io_set\*(C'\fR or \f(CW\*(C`ev_io_modify\*(C'\fR for that.
.PP
\fIExamples\fR
.IX Subsection "Examples"
diff --git a/ev.h b/ev.h
index 65c11e0..d5b9c61 100644
--- a/ev.h
+++ b/ev.h
@@ -694,7 +694,7 @@ EV_API_DECL void ev_resume (EV_P) EV_NOEXCEPT;
ev_set_cb ((ev), cb_); \
} while (0)
-#define ev_io_modify(ev,events_) do { (ev)->events = (ev)->events & EV__IOMASK | (events_); } while (0)
+#define ev_io_modify(ev,events_) do { (ev)->events = (ev)->events & EV__IOFDSET | (events_); } while (0)
#define ev_io_set(ev,fd_,events_) do { (ev)->fd = (fd_); (ev)->events = (events_) | EV__IOFDSET; } while (0)
#define ev_timer_set(ev,after_,repeat_) do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0)
#define ev_periodic_set(ev,ofs_,ival_,rcb_) do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb = (rcb_); } while (0)
@@ -740,6 +740,7 @@ EV_API_DECL void ev_resume (EV_P) EV_NOEXCEPT;
#define ev_periodic_at(ev) (+((ev_watcher_time *)(ev))->at)
#ifndef ev_set_cb
+/* memmove is used here to avoid strict aliasing violations, and hopefully is optimized out by any reasonable compiler */
# define ev_set_cb(ev,cb_) (ev_cb_ (ev) = (cb_), memmove (&((ev_watcher *)(ev))->cb, &ev_cb_ (ev), sizeof (ev_cb_ (ev))))
#endif
diff --git a/ev.pod b/ev.pod
index a88d811..07786f4 100644
--- a/ev.pod
+++ b/ev.pod
@@ -1220,8 +1220,9 @@ with a watcher-specific start function (C<< ev_TYPE_start (loop, watcher
corresponding stop function (C<< ev_TYPE_stop (loop, watcher *) >>.
As long as your watcher is active (has been started but not stopped) you
-must not touch the values stored in it. Most specifically you must never
-reinitialise it or call its C<ev_TYPE_set> macro.
+must not touch the values stored in it except when explicitly documented
+otherwise. Most specifically you must never reinitialise it or call its
+C<ev_TYPE_set> macro.
Each and every callback receives the event loop pointer as first, the
registered watcher structure as second, and a bitset of received events as
@@ -1848,9 +1849,9 @@ C<ev_io_set> for that.
=item int events [no-modify]
-The set of events being watched, among other flags. This field is a
-bit set - to test for C<EV_READ>, use C<< w->events & EV_READ >>, and
-similarly for C<EV_WRITE>.
+The set of events the fd is being watched for, among other flags. Remember
+that this is a bit set - to test for C<EV_READ>, use C<< w->events &
+EV_READ >>, and similarly for C<EV_WRITE>.
As with C<fd>, you must not modify this member even when the watcher is
stopped, always use C<ev_io_set> or C<ev_io_modify> for that.