summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgregor herrmann <gregoa@debian.org>2023-10-27 02:41:59 +0200
committergregor herrmann <gregoa@debian.org>2023-10-27 02:41:59 +0200
commit9c91c8568016d18380b95a544de3bdf2923b1151 (patch)
tree580ea538157e24a740252745f95ba88e3385146f
parentb4decbc47f88f438edca0aa067b652fd86a86339 (diff)
parent11f4ac7c15c5543e782a4a295f1c8c77110b632a (diff)
Update upstream source from tag 'upstream/4.34'
Update to upstream version '4.34' with Debian dir 6d6027204ec1d8fc7cdc715b90238db2a22d03ea
-rw-r--r--Changes5
-rw-r--r--EV.pm13
-rw-r--r--EV.xs9
-rw-r--r--META.json5
-rw-r--r--META.yml5
-rw-r--r--README12
-rw-r--r--libev/Changes7
-rw-r--r--libev/README10
-rw-r--r--libev/ev.c36
-rw-r--r--libev/ev.h2
-rw-r--r--libev/ev.pod80
-rw-r--r--libev/ev_iouring.c124
-rw-r--r--libev/ev_linuxaio.c2
-rw-r--r--libev/ev_port.c10
-rw-r--r--libev/ev_vars.h6
-rw-r--r--libev/ev_wrap.h12
16 files changed, 208 insertions, 130 deletions
diff --git a/Changes b/Changes
index d8b8a1c..04ac7a2 100644
--- a/Changes
+++ b/Changes
@@ -3,6 +3,11 @@ Revision history for Perl extension EV
Changes marked with (libev) are changes in libev, and might have more
documentation in the libev Changes file.
+4.34 Sun 08 Oct 2023 23:45:11 CEST
+ - the EV::stat->path method errornously freed the result, causing
+ corruption (testcase by Carsten Witt).
+ - new functino EV::Child::reinit.
+
4.33 Wed Mar 18 13:31:12 CET 2020
- the enable assertion makefile question failed to enable
assertions due to a typo.
diff --git a/EV.pm b/EV.pm
index bfa64e4..0af0b88 100644
--- a/EV.pm
+++ b/EV.pm
@@ -121,7 +121,7 @@ package EV;
use common::sense;
BEGIN {
- our $VERSION = '4.33';
+ our $VERSION = '4.34';
use XSLoader;
local $^W = 0; # avoid spurious warning
XSLoader::load "EV", $VERSION;
@@ -875,6 +875,17 @@ in perlfunc).
Return the pid of the awaited child (useful when you have installed a
watcher for all pids).
+=item EV::Child::reinit [EXPERIMENTAL]
+
+Internally, libev installs a signal handler for C<SIGCHLD>. Unfortunately,
+a lot of Perl code does soemthing like C<< local $SIG{CHLD} >>, which,
+unfortunately, is broken and will not restore the signal handler.
+
+If this has happened, you can call this function to stop/rrestart the
+internal libev watcher, which will reset the signal handler.
+
+Note that this is an experimental function, whose interface might change.
+
=back
diff --git a/EV.xs b/EV.xs
index 72c59fa..2d34fc1 100644
--- a/EV.xs
+++ b/EV.xs
@@ -1272,6 +1272,11 @@ MODULE = EV PACKAGE = EV::Child PREFIX = ev_child_
#if EV_CHILD_ENABLE
+void ev_child_reinit ()
+ CODE:
+ ev_signal_stop (evapi.default_loop, &childev);
+ ev_signal_start (evapi.default_loop, &childev);
+
void ev_child_start (ev_child *w)
CODE:
START (child, w);
@@ -1327,11 +1332,11 @@ void set (ev_stat *w, SV *path, NV interval)
SV *path (ev_stat *w, SV *new_path = NO_INIT)
CODE:
{
- RETVAL = e_fh (w) ? e_fh (w) : &PL_sv_undef;
+ RETVAL = e_fh (w) ? newSVsv (e_fh (w)) : &PL_sv_undef;
if (items > 1)
{
- sv_2mortal (RETVAL);
+ sv_2mortal (e_fh (w));
e_fh (w) = newSVsv (new_path);
RESET (stat, w, (w, SvPVbyte_nolen (e_fh (w)), w->interval));
}
diff --git a/META.json b/META.json
index 69951ff..3580136 100644
--- a/META.json
+++ b/META.json
@@ -4,7 +4,7 @@
"unknown"
],
"dynamic_config" : 1,
- "generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150001",
+ "generated_by" : "ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version 2.150010",
"license" : [
"unknown"
],
@@ -38,5 +38,6 @@
}
},
"release_status" : "stable",
- "version" : "4.33"
+ "version" : "4.34",
+ "x_serialization_backend" : "JSON::PP version 2.27300"
}
diff --git a/META.yml b/META.yml
index 5a67c94..74acc97 100644
--- a/META.yml
+++ b/META.yml
@@ -8,7 +8,7 @@ configure_requires:
Canary::Stability: '0'
ExtUtils::MakeMaker: '6.52'
dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150001'
+generated_by: 'ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version 2.150010'
license: unknown
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -20,4 +20,5 @@ no_index:
- inc
requires:
common::sense: '0'
-version: '4.33'
+version: '4.34'
+x_serialization_backend: 'CPAN::Meta::YAML version 0.012'
diff --git a/README b/README
index 08f12d8..8802800 100644
--- a/README
+++ b/README
@@ -718,6 +718,18 @@ WATCHER TYPES
Return the pid of the awaited child (useful when you have installed
a watcher for all pids).
+ EV::Child::reinit [EXPERIMENTAL]
+ Internally, libev installs a signal handler for "SIGCHLD".
+ Unfortunately, a lot of Perl code does soemthing like "local
+ $SIG{CHLD}", which, unfortunately, is broken and will not restore
+ the signal handler.
+
+ If this has happened, you can call this function to stop/rrestart
+ the internal libev watcher, which will reset the signal handler.
+
+ Note that this is an experimental function, whose interface might
+ change.
+
STAT WATCHERS - did the file attributes just change?
$w = EV::stat $path, $interval, $callback
$w = EV::stat_ns $path, $interval, $callback
diff --git a/libev/Changes b/libev/Changes
index d200b9e..adc2393 100644
--- a/libev/Changes
+++ b/libev/Changes
@@ -2,6 +2,13 @@ Revision history for libev, a high-performance and full-featured event loop.
TODO: for next ABI/API change, consider moving EV__IOFDSSET into io->fd instead and provide a getter.
TODO: document EV_TSTAMP_T
+TODO: https://paste.debian.net/1268417/, stdfun
+
+4.34 (EV only)
+ - libev did not compile on systems lacking clock_gettime.
+ - due to a logic bug, timerfd availability did not always translate
+ into fewer wakeups - libev is now more aggressive in using
+ longer sleeps, even when timerfd is not in use.
4.33 Wed Mar 18 13:22:29 CET 2020
- no changes w.r.t. 4.32.
diff --git a/libev/README b/libev/README
index fca5fdf..a044ac8 100644
--- a/libev/README
+++ b/libev/README
@@ -9,7 +9,7 @@ ABOUT
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Library Documentation: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod
- Libev is modelled (very losely) after libevent and the Event perl
+ Libev is modelled (very loosely) after libevent and the Event perl
module, but is faster, scales better and is more correct, and also more
featureful. And also smaller. Yay.
@@ -38,10 +38,10 @@ ABOUT
- support for other languages (multiple C++ interfaces, D, Ruby,
Python) available from third-parties.
- Examples of programs that embed libev: the EV perl module, node.js,
- auditd, rxvt-unicode, gvpe (GNU Virtual Private Ethernet), the
- Deliantra MMORPG server (http://www.deliantra.net/), Rubinius (a
- next-generation Ruby VM), the Ebb web server, the Rev event toolkit.
+ Examples of programs that embed libev: the EV perl module, auditd,
+ rxvt-unicode, gvpe (GNU Virtual Private Ethernet), the Deliantra MMORPG
+ server (http://www.deliantra.net/), Rubinius (a next-generation Ruby
+ VM), the Ebb web server, the Rev event toolkit.
CONTRIBUTORS
diff --git a/libev/ev.c b/libev/ev.c
index 7145309..2f98fff 100644
--- a/libev/ev.c
+++ b/libev/ev.c
@@ -37,6 +37,10 @@
* either the BSD or the GPL.
*/
+#pragma clang diagnostic ignored "-Wunused-value"
+#pragma clang diagnostic ignored "-Wcomment"
+#pragma clang diagnostic ignored "-Wextern-initializer"
+
/* this big block deduces configuration from config.h */
#ifndef EV_STANDALONE
# ifdef EV_CONFIG_H
@@ -493,10 +497,10 @@
#if EV_USE_IOURING
# include <sys/syscall.h>
-# if !SYS_io_uring_setup && __linux && !__alpha
-# define SYS_io_uring_setup 425
-# define SYS_io_uring_enter 426
-# define SYS_io_uring_wregister 427
+# if !SYS_io_uring_register && __linux && !__alpha
+# define SYS_io_uring_setup 425
+# define SYS_io_uring_enter 426
+# define SYS_io_uring_register 427
# endif
# if SYS_io_uring_setup && EV_USE_EPOLL /* iouring backend requires epoll backend */
# define EV_NEED_SYSCALL 1
@@ -2394,7 +2398,7 @@ fd_reify (EV_P)
{
int i;
- /* most backends do not modify the fdchanges list in backend_modfiy.
+ /* most backends do not modify the fdchanges list in backend_modify.
* except io_uring, which has fixed-size buffers which might force us
* to handle events in backend_modify, causing fdchanges to be amended,
* which could result in an endless loop.
@@ -3167,7 +3171,7 @@ ev_recommended_backends (void) EV_NOEXCEPT
#if !EV_RECOMMEND_LINUXAIO
flags &= ~EVBACKEND_LINUXAIO;
#endif
- /* TODO: linuxaio is super experimental */
+ /* TODO: iouring is super experimental */
#if !EV_RECOMMEND_IOURING
flags &= ~EVBACKEND_IOURING;
#endif
@@ -3506,7 +3510,7 @@ loop_fork (EV_P)
if (postfork != 2)
{
#if EV_USE_SIGNALFD
- /* surprisingly, nothing needs to be done for signalfd, accoridng to docs, it does the right thing on fork */
+ /* surprisingly, nothing needs to be done for signalfd, according to docs, it does the right thing on fork */
#endif
#if EV_USE_TIMERFD
@@ -4094,16 +4098,20 @@ ev_run (EV_P_ int flags)
{
waittime = EV_TS_CONST (MAX_BLOCKTIME);
+#if EV_USE_MONOTONIC
+ if (ecb_expect_true (have_monotonic))
+ {
#if EV_USE_TIMERFD
- /* sleep a lot longer when we can reliably detect timejumps */
- if (ecb_expect_true (timerfd >= 0))
- waittime = EV_TS_CONST (MAX_BLOCKTIME2);
+ /* sleep a lot longer when we can reliably detect timejumps */
+ if (ecb_expect_true (timerfd != -1))
+ waittime = EV_TS_CONST (MAX_BLOCKTIME2);
#endif
#if !EV_PERIODIC_ENABLE
- /* without periodics but with monotonic clock there is no need */
- /* for any time jump detection, so sleep longer */
- if (ecb_expect_true (have_monotonic))
- waittime = EV_TS_CONST (MAX_BLOCKTIME2);
+ /* without periodics but with monotonic clock there is no need */
+ /* for any time jump detection, so sleep longer */
+ waittime = EV_TS_CONST (MAX_BLOCKTIME2);
+#endif
+ }
#endif
if (timercnt)
diff --git a/libev/ev.h b/libev/ev.h
index 4669c39..0771945 100644
--- a/libev/ev.h
+++ b/libev/ev.h
@@ -744,7 +744,7 @@ EV_API_DECL void ev_resume (EV_P) EV_NOEXCEPT;
# define ev_set_cb(ev,cb_) (ev_cb_ (ev) = (cb_), memmove (&((ev_watcher *)(ev))->cb, &ev_cb_ (ev), sizeof (ev_cb_ (ev))))
#endif
-/* stopping (enabling, adding) a watcher does nothing if it is already running */
+/* starting (enabling, adding) a watcher does nothing if it is already running */
/* stopping (disabling, deleting) a watcher does nothing unless it's already running */
#if EV_PROTOTYPES
diff --git a/libev/ev.pod b/libev/ev.pod
index e4eeb50..0088bc1 100644
--- a/libev/ev.pod
+++ b/libev/ev.pod
@@ -677,8 +677,8 @@ immensely.
=item C<EVBACKEND_PORT> (value 32, Solaris 10)
-This uses the Solaris 10 event port mechanism. As with everything on Solaris,
-it's really slow, but it still scales very well (O(active_fds)).
+This uses the Solaris 10 event port mechanism. As with everything on
+Solaris, it's really slow, but it still scales very well (O(active_fds)).
While this backend scales well, it requires one system call per active
file descriptor per loop iteration. For small and medium numbers of file
@@ -961,8 +961,8 @@ future versions):
- Queue all idle watchers with priority higher than that of pending events.
- Queue all check watchers.
- Call all queued watchers in reverse order (i.e. check watchers first).
- Signals and child watchers are implemented as I/O watchers, and will
- be handled here by queueing them when their watcher gets executed.
+ Signals, async and child watchers are implemented as I/O watchers, and
+ will be handled here by queueing them when their watcher gets executed.
- If ev_break has been called, or EVRUN_ONCE or EVRUN_NOWAIT
were used, or there are no active watchers, goto FINISH, otherwise
continue with step LOOP.
@@ -1398,7 +1398,10 @@ therefore a good idea to always call its C<ev_TYPE_stop> function.
Returns a true value iff the watcher is active (i.e. it has been started
and not yet been stopped). As long as a watcher is active you must not modify
-it.
+it unless documented otherwise.
+
+Obviously, it is safe to call this on an active watcher, or actually any
+watcher that is initialised.
=item bool ev_is_pending (ev_TYPE *watcher)
@@ -1409,6 +1412,9 @@ C<ev_TYPE_set> is safe), you must not change its priority, and you must
make sure the watcher is available to libev (e.g. you cannot C<free ()>
it).
+It is safe to call this on any watcher in any state as long as it is
+initialised.
+
=item callback ev_cb (ev_TYPE *watcher)
Returns the callback currently set on the watcher.
@@ -1431,8 +1437,8 @@ from being executed (except for C<ev_idle> watchers).
If you need to suppress invocation when higher priority events are pending
you need to look at C<ev_idle> watchers, which provide this functionality.
-You I<must not> change the priority of a watcher as long as it is active or
-pending.
+You I<must not> change the priority of a watcher as long as it is active
+or pending. Reading the priority with C<ev_priority> is fine in any state.
Setting a priority outside the range of C<EV_MINPRI> to C<EV_MAXPRI> is
fine, as long as you do not mind that the priority value you query might
@@ -1464,8 +1470,9 @@ callback to be invoked, which can be accomplished with this function.
Feeds the given event set into the event loop, as if the specified event
had happened for the specified watcher (which must be a pointer to an
-initialised but not necessarily started event watcher). Obviously you must
-not free the watcher as long as it has pending events.
+initialised but not necessarily started event watcher, though it can be
+active). Obviously you must not free the watcher as long as it has pending
+events.
Stopping the watcher, letting libev invoke it, or calling
C<ev_clear_pending> will clear the pending event, even if the watcher was
@@ -1503,24 +1510,33 @@ C<ev_TYPE_init> again.
Once a watcher has been started with a call to C<ev_TYPE_start> it becomes
property of the event loop, and is actively waiting for events. While in
-this state it cannot be accessed (except in a few documented ways), moved,
-freed or anything else - the only legal thing is to keep a pointer to it,
-and call libev functions on it that are documented to work on active watchers.
+this state it cannot be accessed (except in a few documented ways, such as
+stoping it), moved, freed or anything else - the only legal thing is to
+keep a pointer to it, and call libev functions on it that are documented
+to work on active watchers.
+
+As a rule of thumb, before accessing a member or calling any function on
+a watcher, it should be stopped (or freshly initialised). If that is not
+convenient, you can check the documentation for that function or member to
+see if it is safe to use on an active watcher.
=item pending
If a watcher is active and libev determines that an event it is interested
-in has occurred (such as a timer expiring), it will become pending. It will
-stay in this pending state until either it is stopped or its callback is
-about to be invoked, so it is not normally pending inside the watcher
-callback.
+in has occurred (such as a timer expiring), it will become pending. It
+will stay in this pending state until either it is explicitly stopped or
+its callback is about to be invoked, so it is not normally pending inside
+the watcher callback.
+
+Generally, the watcher might or might not be active while it is pending
+(for example, an expired non-repeating timer can be pending but no longer
+active). If it is pending but not active, it can be freely accessed (e.g.
+by calling C<ev_TYPE_set>), but it is still property of the event loop at
+this time, so cannot be moved, freed or reused. And if it is active the
+rules described in the previous item still apply.
-The watcher might or might not be active while it is pending (for example,
-an expired non-repeating timer can be pending but no longer active). If it
-is stopped, it can be freely accessed (e.g. by calling C<ev_TYPE_set>),
-but it is still property of the event loop at this time, so cannot be
-moved, freed or reused. And if it is active the rules described in the
-previous item still apply.
+Explicitly stopping a watcher will also clear the pending state
+unconditionally, so it is safe to stop a watcher and then free it.
It is also possible to feed an event on a watcher that is not active (e.g.
via C<ev_feed_event>), in which case it becomes pending without being
@@ -3864,10 +3880,10 @@ event loop thread and an unspecified mechanism to wake up the main thread.
First, you need to associate some data with the event loop:
typedef struct {
- mutex_t lock; /* global loop lock */
+ pthread_mutex_t lock; /* global loop lock */
+ pthread_t tid;
+ pthread_cond_t invoke_cv;
ev_async async_w;
- thread_t tid;
- cond_t invoke_cv;
} userdata;
void prepare_loop (EV_P)
@@ -3875,19 +3891,19 @@ First, you need to associate some data with the event loop:
// for simplicity, we use a static userdata struct.
static userdata u;
- ev_async_init (&u->async_w, async_cb);
- ev_async_start (EV_A_ &u->async_w);
+ ev_async_init (&u.async_w, async_cb);
+ ev_async_start (EV_A_ &u.async_w);
- pthread_mutex_init (&u->lock, 0);
- pthread_cond_init (&u->invoke_cv, 0);
+ pthread_mutex_init (&u.lock, 0);
+ pthread_cond_init (&u.invoke_cv, 0);
// now associate this with the loop
- ev_set_userdata (EV_A_ u);
+ ev_set_userdata (EV_A_ &u);
ev_set_invoke_pending_cb (EV_A_ l_invoke);
ev_set_loop_release_cb (EV_A_ l_release, l_acquire);
// then create the thread running ev_run
- pthread_create (&u->tid, 0, l_run, EV_A);
+ pthread_create (&u.tid, 0, l_run, EV_A);
}
The callback for the C<ev_async> watcher does nothing: the watcher is used
@@ -4270,7 +4286,7 @@ For C<ev::embed> watchers this method is called C<set_embed>, to avoid
clashing with the C<set (loop)> method.
For C<ev::io> watchers there is an additional C<set> method that acepts a
-new event mask only, and internally calls C<ev_io_modfify>.
+new event mask only, and internally calls C<ev_io_modify>.
=item w->start ()
diff --git a/libev/ev_iouring.c b/libev/ev_iouring.c
index bfd3de6..52d2e1a 100644
--- a/libev/ev_iouring.c
+++ b/libev/ev_iouring.c
@@ -61,13 +61,13 @@
* applications, to the detriment of everybody else who just wants
* an event loop. but, umm, ok, if that's all, it could be worse.
* (from what I gather from the author Jens Axboe, it simply didn't
- * occur to him, and he made good on it by adding an unlimited nuber
+ * occur to him, and he made good on it by adding an unlimited number
* of timeouts later :).
* h) initially there was a hardcoded limit of 4096 outstanding events.
* later versions not only bump this to 32k, but also can handle
* an unlimited amount of events, so this only affects the batch size.
* i) unlike linux aio, you *can* register more then the limit
- * of fd events. while early verisons of io_uring signalled an overflow
+ * of fd events. while early versions of io_uring signalled an overflow
* and you ended up getting wet. 5.5+ does not do this anymore.
* j) but, oh my! it had exactly the same bugs as the linux aio backend,
* where some undocumented poll combinations just fail. fortunately,
@@ -120,10 +120,12 @@ struct io_uring_sqe
__u32 cancel_flags;
__u32 open_flags;
__u32 statx_flags;
+ __u32 fadvise_advice;
};
__u64 user_data;
union {
__u16 buf_index;
+ __u16 personality;
__u64 __pad2[3];
};
};
@@ -172,13 +174,40 @@ struct io_uring_params
struct io_cqring_offsets cq_off;
};
+#define IORING_FEAT_SINGLE_MMAP 0x00000001
+#define IORING_FEAT_NODROP 0x00000002
+#define IORING_FEAT_SUBMIT_STABLE 0x00000004
+
#define IORING_SETUP_CQSIZE 0x00000008
+#define IORING_SETUP_CLAMP 0x00000010
#define IORING_OP_POLL_ADD 6
#define IORING_OP_POLL_REMOVE 7
#define IORING_OP_TIMEOUT 11
#define IORING_OP_TIMEOUT_REMOVE 12
+#define IORING_REGISTER_EVENTFD 4
+#define IORING_REGISTER_EVENTFD_ASYNC 7
+#define IORING_REGISTER_PROBE 8
+
+#define IO_URING_OP_SUPPORTED 1
+
+struct io_uring_probe_op {
+ __u8 op;
+ __u8 resv;
+ __u16 flags;
+ __u32 resv2;
+};
+
+struct io_uring_probe
+{
+ __u8 last_op;
+ __u8 ops_len;
+ __u16 resv;
+ __u32 resv2[3];
+ struct io_uring_probe_op ops[0];
+};
+
/* relative or absolute, reference clock is CLOCK_MONOTONIC */
struct iouring_kernel_timespec
{
@@ -191,7 +220,6 @@ struct iouring_kernel_timespec
#define IORING_ENTER_GETEVENTS 0x01
#define IORING_OFF_SQ_RING 0x00000000ULL
-#define IORING_OFF_CQ_RING 0x08000000ULL
#define IORING_OFF_SQES 0x10000000ULL
#define IORING_FEAT_SINGLE_MMAP 0x00000001
@@ -212,19 +240,26 @@ evsys_io_uring_enter (int fd, unsigned to_submit, unsigned min_complete, unsigne
return ev_syscall6 (SYS_io_uring_enter, fd, to_submit, min_complete, flags, sig, sigsz);
}
+inline_size
+int
+evsys_io_uring_register (unsigned int fd, unsigned int opcode, void *arg, unsigned int nr_args)
+{
+ return ev_syscall4 (SYS_io_uring_register, fd, opcode, arg, nr_args);
+}
+
/*****************************************************************************/
-/* actual backed implementation */
+/* actual backend implementation */
/* we hope that volatile will make the compiler access this variables only once */
-#define EV_SQ_VAR(name) *(volatile unsigned *)((char *)iouring_sq_ring + iouring_sq_ ## name)
-#define EV_CQ_VAR(name) *(volatile unsigned *)((char *)iouring_cq_ring + iouring_cq_ ## name)
+#define EV_SQ_VAR(name) *(volatile unsigned *)((char *)iouring_ring + iouring_sq_ ## name)
+#define EV_CQ_VAR(name) *(volatile unsigned *)((char *)iouring_ring + iouring_cq_ ## name)
/* the index array */
-#define EV_SQ_ARRAY ((unsigned *)((char *)iouring_sq_ring + iouring_sq_array))
+#define EV_SQ_ARRAY ((unsigned *)((char *)iouring_ring + iouring_sq_array))
/* the submit/completion queue entries */
#define EV_SQES ((struct io_uring_sqe *) iouring_sqes)
-#define EV_CQES ((struct io_uring_cqe *)((char *)iouring_cq_ring + iouring_cq_cqes))
+#define EV_CQES ((struct io_uring_cqe *)((char *)iouring_ring + iouring_cq_cqes))
inline_speed
int
@@ -287,7 +322,7 @@ iouring_sqe_get (EV_P)
}
inline_size
-struct io_uring_sqe *
+void
iouring_sqe_submit (EV_P_ struct io_uring_sqe *sqe)
{
unsigned idx = sqe - EV_SQES;
@@ -313,15 +348,14 @@ iouring_tfd_cb (EV_P_ struct ev_io *w, int revents)
/* called for full and partial cleanup */
ecb_cold
-static int
+static void
iouring_internal_destroy (EV_P)
{
close (iouring_tfd);
close (iouring_fd);
- if (iouring_sq_ring != MAP_FAILED) munmap (iouring_sq_ring, iouring_sq_ring_size);
- if (iouring_cq_ring != MAP_FAILED) munmap (iouring_cq_ring, iouring_cq_ring_size);
- if (iouring_sqes != MAP_FAILED) munmap (iouring_sqes , iouring_sqes_size );
+ if (iouring_ring != MAP_FAILED) munmap (iouring_ring, iouring_ring_size);
+ if (iouring_sqes != MAP_FAILED) munmap (iouring_sqes, iouring_sqes_size);
if (ev_is_active (&iouring_tfd_w))
{
@@ -335,57 +369,41 @@ static int
iouring_internal_init (EV_P)
{
struct io_uring_params params = { 0 };
+ uint32_t sq_size, cq_size;
+
+ params.flags = IORING_SETUP_CLAMP;
iouring_to_submit = 0;
- iouring_tfd = -1;
- iouring_sq_ring = MAP_FAILED;
- iouring_cq_ring = MAP_FAILED;
- iouring_sqes = MAP_FAILED;
+ iouring_tfd = -1;
+ iouring_ring = MAP_FAILED;
+ iouring_sqes = MAP_FAILED;
if (!have_monotonic) /* cannot really happen, but what if11 */
return -1;
- for (;;)
- {
- iouring_fd = evsys_io_uring_setup (iouring_entries, &params);
-
- if (iouring_fd >= 0)
- break; /* yippie */
+ iouring_fd = evsys_io_uring_setup (iouring_entries, &params);
- if (errno != EINVAL)
- return -1; /* we failed */
-
-#if TODO
- if ((~params.features) & (IORING_FEAT_NODROP | IORING_FEATURE_SINGLE_MMAP | IORING_FEAT_SUBMIT_STABLE))
- return -1; /* we require the above features */
-#endif
+ if (iouring_fd < 0)
+ return -1;
- /* EINVAL: lots of possible reasons, but maybe
- * it is because we hit the unqueryable hardcoded size limit
- */
+ if ((~params.features) & (IORING_FEAT_NODROP | IORING_FEAT_SINGLE_MMAP | IORING_FEAT_SUBMIT_STABLE))
+ return -1; /* we require the above features */
- /* we hit the limit already, give up */
- if (iouring_max_entries)
- return -1;
+ /* TODO: remember somehow whether our queue size has been clamped */
- /* first time we hit EINVAL? assume we hit the limit, so go back and retry */
- iouring_entries >>= 1;
- iouring_max_entries = iouring_entries;
- }
+ sq_size = params.sq_off.array + params.sq_entries * sizeof (unsigned);
+ cq_size = params.cq_off.cqes + params.cq_entries * sizeof (struct io_uring_cqe);
- iouring_sq_ring_size = params.sq_off.array + params.sq_entries * sizeof (unsigned);
- iouring_cq_ring_size = params.cq_off.cqes + params.cq_entries * sizeof (struct io_uring_cqe);
- iouring_sqes_size = params.sq_entries * sizeof (struct io_uring_sqe);
+ iouring_ring_size = sq_size > cq_size ? sq_size : cq_size;
+ iouring_sqes_size = params.sq_entries * sizeof (struct io_uring_sqe);
- iouring_sq_ring = mmap (0, iouring_sq_ring_size, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_POPULATE, iouring_fd, IORING_OFF_SQ_RING);
- iouring_cq_ring = mmap (0, iouring_cq_ring_size, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_POPULATE, iouring_fd, IORING_OFF_CQ_RING);
- iouring_sqes = mmap (0, iouring_sqes_size, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_POPULATE, iouring_fd, IORING_OFF_SQES);
+ iouring_ring = mmap (0, iouring_ring_size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_POPULATE, iouring_fd, IORING_OFF_SQ_RING);
+ iouring_sqes = mmap (0, iouring_sqes_size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_POPULATE, iouring_fd, IORING_OFF_SQES);
- if (iouring_sq_ring == MAP_FAILED || iouring_cq_ring == MAP_FAILED || iouring_sqes == MAP_FAILED)
+ if (iouring_ring == MAP_FAILED || iouring_sqes == MAP_FAILED)
return -1;
iouring_sq_head = params.sq_off.head;
@@ -403,12 +421,12 @@ iouring_internal_init (EV_P)
iouring_cq_overflow = params.cq_off.overflow;
iouring_cq_cqes = params.cq_off.cqes;
+ iouring_tfd_to = EV_TSTAMP_HUGE;
+
iouring_tfd = timerfd_create (CLOCK_MONOTONIC, TFD_CLOEXEC);
if (iouring_tfd < 0)
- return iouring_tfd;
-
- iouring_tfd_to = EV_TSTAMP_HUGE;
+ return -1;
return 0;
}
diff --git a/libev/ev_linuxaio.c b/libev/ev_linuxaio.c
index 4687a70..0eb705a 100644
--- a/libev/ev_linuxaio.c
+++ b/libev/ev_linuxaio.c
@@ -93,7 +93,7 @@
#include <sys/syscall.h> /* no glibc wrappers */
-/* aio_abi.h is not versioned in any way, so we cannot test for its existance */
+/* aio_abi.h is not versioned in any way, so we cannot test for its existence */
#define IOCB_CMD_POLL 5
/* taken from linux/fs/aio.c. yup, that's a .c file.
diff --git a/libev/ev_port.c b/libev/ev_port.c
index f4cd9d9..d611459 100644
--- a/libev/ev_port.c
+++ b/libev/ev_port.c
@@ -39,10 +39,10 @@
/* useful reading:
*
- * http://bugs.opensolaris.org/view_bug.do?bug_id=6268715 (random results)
- * http://bugs.opensolaris.org/view_bug.do?bug_id=6455223 (just totally broken)
- * http://bugs.opensolaris.org/view_bug.do?bug_id=6873782 (manpage ETIME)
- * http://bugs.opensolaris.org/view_bug.do?bug_id=6874410 (implementation ETIME)
+ * https://archive.is/jN6Ck (random results)
+ * https://archive.is/bBikp (just totally broken)
+ * https://archive.is/eJhmu (manpage ETIME)
+ * https://archive.is/RbgYw (implementation ETIME)
* http://www.mail-archive.com/networking-discuss@opensolaris.org/msg11898.html ETIME vs. nget
* http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/event_port.c (libc)
* http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/fs/portfs/port.c#1325 (kernel)
@@ -113,7 +113,7 @@ port_poll (EV_P_ ev_tstamp timeout)
/* port_getn may or may not set nget on error */
/* so we rely on port_events [0].portev_source not being updated */
if (res == -1 && errno != ETIME && errno != EINTR)
- ev_syserr ("(libev) port_getn (see http://bugs.opensolaris.org/view_bug.do?bug_id=6268715, try LIBEV_FLAGS=3 env variable)");
+ ev_syserr ("(libev) port_getn (see https://archive.is/jN6Ck, try LIBEV_FLAGS=3 env variable)");
for (i = 0; i < nget; ++i)
{
diff --git a/libev/ev_vars.h b/libev/ev_vars.h
index fb0c583..5ce8301 100644
--- a/libev/ev_vars.h
+++ b/libev/ev_vars.h
@@ -123,11 +123,9 @@ VARx(int, iouring_fd)
VARx(unsigned, iouring_to_submit);
VARx(int, iouring_entries)
VARx(int, iouring_max_entries)
-VARx(void *, iouring_sq_ring)
-VARx(void *, iouring_cq_ring)
+VARx(void *, iouring_ring)
VARx(void *, iouring_sqes)
-VARx(uint32_t, iouring_sq_ring_size)
-VARx(uint32_t, iouring_cq_ring_size)
+VARx(uint32_t, iouring_ring_size)
VARx(uint32_t, iouring_sqes_size)
VARx(uint32_t, iouring_sq_head)
VARx(uint32_t, iouring_sq_tail)
diff --git a/libev/ev_wrap.h b/libev/ev_wrap.h
index 45d793c..b038bb9 100644
--- a/libev/ev_wrap.h
+++ b/libev/ev_wrap.h
@@ -47,22 +47,20 @@
#define iouring_cq_cqes ((loop)->iouring_cq_cqes)
#define iouring_cq_head ((loop)->iouring_cq_head)
#define iouring_cq_overflow ((loop)->iouring_cq_overflow)
-#define iouring_cq_ring ((loop)->iouring_cq_ring)
#define iouring_cq_ring_entries ((loop)->iouring_cq_ring_entries)
#define iouring_cq_ring_mask ((loop)->iouring_cq_ring_mask)
-#define iouring_cq_ring_size ((loop)->iouring_cq_ring_size)
#define iouring_cq_tail ((loop)->iouring_cq_tail)
#define iouring_entries ((loop)->iouring_entries)
#define iouring_fd ((loop)->iouring_fd)
#define iouring_max_entries ((loop)->iouring_max_entries)
+#define iouring_ring ((loop)->iouring_ring)
+#define iouring_ring_size ((loop)->iouring_ring_size)
#define iouring_sq_array ((loop)->iouring_sq_array)
#define iouring_sq_dropped ((loop)->iouring_sq_dropped)
#define iouring_sq_flags ((loop)->iouring_sq_flags)
#define iouring_sq_head ((loop)->iouring_sq_head)
-#define iouring_sq_ring ((loop)->iouring_sq_ring)
#define iouring_sq_ring_entries ((loop)->iouring_sq_ring_entries)
#define iouring_sq_ring_mask ((loop)->iouring_sq_ring_mask)
-#define iouring_sq_ring_size ((loop)->iouring_sq_ring_size)
#define iouring_sq_tail ((loop)->iouring_sq_tail)
#define iouring_sqes ((loop)->iouring_sqes)
#define iouring_sqes_size ((loop)->iouring_sqes_size)
@@ -182,22 +180,20 @@
#undef iouring_cq_cqes
#undef iouring_cq_head
#undef iouring_cq_overflow
-#undef iouring_cq_ring
#undef iouring_cq_ring_entries
#undef iouring_cq_ring_mask
-#undef iouring_cq_ring_size
#undef iouring_cq_tail
#undef iouring_entries
#undef iouring_fd
#undef iouring_max_entries
+#undef iouring_ring
+#undef iouring_ring_size
#undef iouring_sq_array
#undef iouring_sq_dropped
#undef iouring_sq_flags
#undef iouring_sq_head
-#undef iouring_sq_ring
#undef iouring_sq_ring_entries
#undef iouring_sq_ring_mask
-#undef iouring_sq_ring_size
#undef iouring_sq_tail
#undef iouring_sqes
#undef iouring_sqes_size