| Commit message (Collapse) | Author | Age |
| ... | |
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
| |
This makes the APIs use string keys, and largely eliminates the use of
integer option IDs altogether. The underlying registration for options
is also now a bit richer, letting protcols and transports declare the
actual options they use, rather than calling down into each entry point
carte blanche and relying on ENOTSUP.
This code may not be as fast as the integers was, but it is more intuitive,
easier to extend, and is not on any hot code paths. (If you're diddling
options on a hot code path you're doing something wrong.)
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
We allocate AIO structures dynamically, so that we can use them
abstractly in more places without inlining them. This will be used
for the ZeroTier transport to allow us to create operations consisting
of just the AIO. Furthermore, we provide accessors for some of the
aio members, in the hopes that we will be able to wrap these for
"safe" version of the AIO capability to export to applications, and
to protocol and transport implementors.
While here we cleaned up the protocol details to use consistently
shorter names (no nni_ prefix for static symbols needed), and we
also fixed a bug in the surveyor code.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This eliminates all the old #define's or enum values, making all
option IDs now totally dynamic, and providing well-known string
values for well-behaved applications.
We have added tests of some of these options, including lookups, and
so forth. We have also fixed a few problems; including at least
one crasher bug when the timeouts on reconnect were zero.
Protocol specific options are now handled in the protocol. We will
be moving the initialization for a few of those well known entities
to the protocol startup code, following the PAIRv1 pattern, later.
Applications must therefore not depend on the value of the integer IDs,
at least until the application has opened a socket of the appropriate
type.
|
| |
|
|
|
|
|
|
|
|
|
| |
We intend to use this with transports where dynamic "port numbers"
might be 32-bits. This would allow us to formulate a 64-bit number
representing a conversation, and be able to find that conversation
by the 64-bit value.
Note that the hashed values are probably not perfectly optimal, as
only the low order bits are particularly significant in the hash.
We might want to consider XOR'ing in the upper bits to address that.
|
| |
|
|
|
|
| |
This supports creating listeners and dialers, managing options
on them (though only a few options are supported at present),
starting them and closing them, all independently.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If the underlying platform fails (FreeBSD is the only one I'm aware
of that does this!), we use a global lock or condition variable instead.
This means that our lock initializers never ever fail.
Probably we could eliminate most of this for Linux and Darwin, since
on those platforms, mutex and condvar initialization reasonably never
fails. Initial benchmarks show little difference either way -- so we
can revisit (optimize) later.
This removes a lot of otherwise untested code in error cases and so forth,
improving coverage and resilience in the face of allocation failures.
Platforms other than POSIX should follow a similar pattern if they need
this. (VxWorks, I'm thinking of you.) Most sane platforms won't have
an issue here, since normally these initializations do not need to allocate
memory. (Reportedly, even FreeBSD has plans to "fix" this in libthr2.)
While here, some bugs were fixed in initialization & teardown.
The fallback code is properly tested with dedicated test cases.
|
| |
|
|
|
| |
We enable a few flags, but now the details of the socket internals
are completely private to the socket.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
| |
fixes #66 Make pipe and endpoint structures private
This changes a number of things, refactoring endpoints and supporting
code to keep their internals private, and making endpoint close
synchronous. This will allow us to add a consumer facing API for
nng_ep_close(), as well as property APIs, etc.
While here a bunch of convoluted and dead code was cleaned up.
|
| |
|
|
|
|
|
| |
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 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.
|
| |
|
|
| |
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.)
|
| |
|
|
|
|
|
| |
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 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 leaks of pipes causing test failures (e.g. the Windows
IPC test) due to EADDRINUSE. This was caused by a case where we
failed to pass the pipe up because the AIO had already been canceled,
and we didn't realize that we had oprhaned the pipe. The fix is to
add a return value to nni_aio_finish, and verify that we did finish
properly, or if we did not then we must free the pipe ourself. (The
zero return from nni_aio_finish indicates that it accepts ownership
of resources passed via the aio.)
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
| |
This cleans up the pipe creation logic greatly, and eliminates
a nasty potential deadlock (lock-order incorrect.) It also
adds a corret binary exponential and randomized backoff on both
accept and connect.
|
| |
|
|
|
|
| |
This actually is breaking at the moment, because we don't have
good integration with timeouts, and there are some frustrating
races with timeouts at points that can cause apparent hangs.
|
| |
|
|
|
|
| |
This logic leaves a race condition in the dial side, which will
be fixed with a subsequent change to convert that to fully asynchronous
as well.
|
| |
|
|
|
|
| |
We still have endpoint related races apparently; we need to examine
the possibility of handling endpoints much like we do pipes, which seem
to be race free.
|
| | |
|
| |
|
|
|
|
|
|
|
| |
Modern Windows (Vista and later) have light weight Slim Read/Write locks
which only occupy 64 bits, and don't require any memory allocation to
create.
While here clean up a few more unreferenced variables found with the
Microsoft compilers.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It turns out that I had to fix a number of subtle asynchronous
handling bugs, but now TCP is fully asynchronous. We need to
change the high-level dial and listen interfaces to be async
as well.
Some of the transport APIs have changed here, and I've elected
to change what we expose to consumers as endpoints into seperate
dialers and listeners. Under the hood they are the same, but
it turns out that its helpful to know the intended use of the
endpoint at initialization time.
Scalability still occasionally hangs on Linux. Investigation
pending.
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|