| Commit message (Collapse) | Author | Age |
| | |
|
| | |
|
| |
|
|
|
|
|
| |
This fixes one major problem, which was that if nni_fini() was called
once on Windows, it would not be further possible to call nni_init().
While here fixed a few compilation issues.
|
| | |
|
| |
|
|
|
| |
This creates a use-after-free bug if nni_fini() is run, then new
sockets are created.
|
| | |
|
| |
|
|
|
|
|
| |
We never set the fd->sn_init member, causing new fds to be allocated
on each request for a new pollfd, and causing old ones to leak, and
worse may be even to not get notified. While here, we arrange for
a bit richer testing against the various options.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
This makes the operations that work on headers start with
nni_msg_header or nng_msg_header. It also renames _trunc to
_chop (same strlen as _trim), and renames prepend to insert.
We add a shorthand for clearing message content, and make
better use of the endian safe 32-bit accessors too.
This also fixes a bug in inserting large headers into messages.
A test suite for message handling is included.
|
| |
|
|
|
|
|
|
|
|
| |
The PAIR_V1 protocol supports both raw and cooked modes, and has loop
prevention included. It also has a polyamorous mode, wherein it allows
multiple connections to be established. In polyamorous mode (set by
an option), the sender requests a paritcular pipe by setting it on the
message.
We default to PAIR_V1 now.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
A little benchmarking showed that we were encountering far too many
wakeups, leading to severe performance degradation; we had a bunch
of threads all sleeping on the same condition variable (taskqs)
and this woke them all up, resulting in heavy mutex contention.
Since we only need one of the threads to wake, and we don't care which
one, let's just wake only one. This reduced RTT latency from about
240 us down to about 30 s. (1/8 of the former cost.)
There's still a bunch of tuning to do; performance remains worse than
we would like.
|
| |
|
|
| |
fixes #23 Restore the old idhash logic for sockets
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
fixes #38 Make protocols "pluggable", or at least optional
This is a breaking change, as we've done away with the central
registered list of protocols, and instead demand the user call
nng_xxx_open() where xxx is a protocol name. (We did keep a
table around in the compat framework though.)
There is a nice way for protocols to plug in via
an nni_proto_open(), where they can use a generic constructor
that they use to build a protocol specific constructor (passing
their ops vector in.)
|
| |
|
|
|
|
|
|
|
|
|
|
| |
We automatically register inproc, TCP, and IPC. We can add more now
by just calling nni_tran_register(). (There is no unregister support.)
This requires transports to have access to the AIO framework (so that needs
to be something we consider), and a few nni_sock calls to get socket options.
Going forward we should version the ops vectors, and move to pushing down
transport options from the framework via setopt calls -- there is no reason
really that transports need to know all these.
|
| | |
|
| | |
|
| |
|
|
|
|
|
| |
Hop counts for REQ were busted (bad TTL), and imported the
compat_reqtll test. At the same time, added code to nn_term
to shut down completely, discarding sockets. (Note that some
things, such as globals, may still be left around; that's ok.)
|
| |
|
|
|
|
| |
The finish routine can race against an asynchronous cancellation,
so we must not clear the data pointer, or we can wind up with a
NULL pointer dereference.
|
| |
|
|
|
|
|
|
|
| |
We noticed a bug in the surveyor handling of the options; this fixes
that. At the same time, we noticed a race condition in the setting
of the error for future calls, a short sleep seems to cure it. This
distinction (ESTATE vs ETIMEDOUT) is pretty annoying, and it would be
better to have a different way to handle it. More work here is
warranted.
|
| | |
|
| |
|
|
|
|
|
|
|
| |
We introduced the compat_msg.c from the old msg.c in the nanomsg
repo. While here, we found that the handling for send() was badly
wrong, by a level of indirection. We simplified the code to so that
nn_send() and nn_recv() are simple wrappers around the nn_sendmsg()
and nn_recvmsg() APIs (as in old nanomsg). This may not be quite as
fast, but it's more likely to be correct and reduces complexity.
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
| |
With the new reapers, we've seen some problems caused by the reaper
running after the taskq that they have to wait on (completion tasks
for aios) are destroyed. We need to make sure that we tear down major
subsystems in the correct order.
|
| | |
|
| |
|
|
|
|
|
| |
This change mirrors the change we made for pipes yesterday,
moving the endpoint cleanup to its own thread, ensuring that
the blocking operations we need to perform during clean up
do not gum up the works in the main system taskq.
|
| |
|
|
|
|
|
|
| |
The problem is that reaping these things performs some blocking
operations which can tie up slots in the taskq, preventing other
tasks from running. Ultimately this can lead to a deadlock as
tasks that are blocked wind up waiting for tasks that can't get
scheduled. Blocking tasks really should not run on the system taskq.
|
| | |
|
| |
|
|
|
|
|
|
|
| |
This passes valgrind 100% clean for both helgrind and deep leak
checks. This represents a complete rethink of how the AIOs work,
and much simpler synchronization; the provider API is a bit simpler
to boot, as a number of failure modes have been simply eliminated.
While here a few other minor bugs were squashed.
|
| | |
|
| |
|
|
|
|
| |
This includes async send and recv, driven from the poller. This will
be requierd to support the underlying UDP and ZeroTier transports in
the future. (ZeroTier is getting done first.)
|
| | |
|
| |
|
|
| |
block for any AIO completion.
|
| |
|
|
|
|
|
| |
The queue is bound at initialization time of the task, and we call
entries just tasks, so we don't have to pass around a taskq pointer
across all the calls. Further, nni_task_dispatch is now guaranteed
to succeed.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
| |
We need to remember that protocol stops can run synchronously, and
therefore we need to wait for the aio to complete. Further, we need
to break apart shutting down aio activity from deallocation, as we need
to shut down *all* async activity before deallocating *anything*.
Noticed that we had a pipe race in the surveyor pattern too.
|
| |
|
|
|
|
|
|
| |
We have seen some yet another weird situation where we had an orphaned
pipe, which was caused by not completing the callback. If we are going
to run nni_aio_fini, we should still run the callback (albeit with a
return value of NNG_ECANCELED or somesuch) to be sure that we can't
orphan stuff.
|
| |
|
|
|
|
|
|
|
|
|
| |
This one is caused by us deallocating the msg queue before we
stop all asynchronous I/O operations; consequently we can wind
up with a thread trying to access a msg queue after it has been
destroyed.
A lesson here is that nni_aio_fini() needs to be treated much like
nni_thr_fini() - you should do this *before* deallocating anything
that callback functions might be referencing.
|
| | |
|
| | |
|
| |
|
|
|
|
| |
This resolves the orphaned pipedesc, which actually could have affected
Windows too. I think maybe we are race free. Lots more testing is
still required, but stress runs seem to be passing now.
|
| |
|
|
|
|
| |
Apparently there are circumstances when a pipedesc may get orphaned form the
pollq. This triggers an assertion failure when it occurs. I am still
trying to understand how this can occur. Stay tuned.
|
| | |
|