Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Rust bindings for Enduro/X.
Runtime modes
The default build has no async-runtime dependency. Use AtmiCtx::tpcall for
the normal blocking XATMI call path, or AtmiCtx::tpacall plus
AtmiCtx::tpgetrply when managing Enduro/X call descriptors directly.
Async support uses a runtime-neutral call state machine with an explicitly
selected reply-fd driver. Async features also enable ctx-send, ensuring each
adapter owns a distinct Enduro/X Object API context. Tokio-native integration
is optional:
[]
= { = "0.1", = ["tokio"] }
= { = "1", = ["macros", "net", "rt", "time"] }
For an executor-independent driver backed by the async-io reactor instead:
= { = "0.1", = ["async-io"] }
The async-io adapter's futures can be polled by Tokio, smol, async-std, or
another standard Rust executor. Enabling both tokio and async-io is also
supported; the adapter type determines which reactor a context uses.
Async waiting requires an Enduro/X build whose ndrx_config.h selects
EX_USE_EPOLL or EX_USE_KQUEUE. On other queue backends adapter construction
returns TPEINVAL; use the blocking API from the runtime's blocking-task
facility and create the complete AtmiCtx inside that task.
AtmiCtx is deliberately !Sync, so its async call futures are !Send. Await
them directly on a current-thread runtime or a tokio::task::LocalSet, rather
than passing them to tokio::spawn:
use AtmiCtx;
async
The async signatures match the blocking ones. There is no per-call timeout
argument, because XATMI has none: timeouts come from NDRX_TOUT, tptoutset
and tpsblktime, and the async path reads the effective value with
tpgblktime before each tpacall. For a one-off override, use the same idiom
you would use before a blocking call:
# use ;
# async
Concurrent async calls on one context share a single reactor registration.
Replies are demultiplexed by call descriptor using tpgetrply(TPGETANY), so a
reply wakes exactly the future waiting for it, and no reply is ever diverted
into Enduro/X's in-memory queue where the reply fd could not signal it again.
Dropping AsyncAtmiCtx::tpcall cancels its Enduro/X call descriptor; dropping
AsyncAtmiCtx::tpgetrply leaves its caller-owned descriptor pending so it can
be awaited again or cancelled explicitly. Multiple adapters may share one
executor thread; each owns a separate Enduro/X context and reply queue.
The generic form is AsyncAtmiCtx<D>, where D: AsyncReplyDriver. The provided
drivers are TokioReplyDriver and AsyncIoReplyDriver. Because the adapter
owns AtmiCtx, a context cannot accidentally be registered with two reactors.
Server dispatch threads
AtmiCtx::tp_run enables Enduro/X's multithread-capable integration mode. When
maxdispatchthreads is greater than one, mindispatchthreads worker threads
are created and service callbacks may execute concurrently on any of them.
Each callback receives a worker-local AtmiCtx; with ctx-send it temporarily
uses that worker's OAPI context and restores the worker TLS before returning.
With maxdispatchthreads=1, callbacks stay on the tp_run main thread and use
the owning server context; worker init/done hooks are intentionally not called.
With mindispatchthreads=1 and maxdispatchthreads>1, one worker is created and
its thread init/done hooks are called normally.
Rust integration also uses ATMI_SRVLIB_NOLONGJUMP, so tpreturn and
tpforward return through Rust normally instead of performing a C longjmp
across Rust stack frames. Service handlers must protect any shared application
state because the same handler function can run concurrently.
Testing
Sync mode tests:
$ cargo test
Context-migration tests:
$ cargo test --features ctx-send
Tokio API tests:
$ cargo test --features tokio
Executor-independent async API tests:
$ cargo test --features async-io