This crates helps creating flexible libraries that may work in either multithreaded and singlethreaded environments.
Creating library that works in either desktop/server or web-browser environment could be tough.
In desktop/server environments crates tend to be usable with multiple threads
and add [Send
] and [Sync
] trait bounds where needed.
In the same time [web-sys
] - a de facto standard crate to use browser API -
provides programmer with !Send + !Sync
types that cannot be used when [Send
]
or [Sync
] bounds are placed on the API calls.
For example asset loading crate [goods
] uses generic executors to drive
loading process.
Some executors work with sendable futures only: [tokio
],
some requre sendable future to run them on multiple threads:
[async-std
], [actix-rt
],
Others work with any futures in single thread: [wasm_bindgen_futures::spawn_local
]
In [goods
] one of the basic data sources for web - [FetchSource
] - uses
browser's Fetch API to retreive data from web and produces non-sendable future.
That's why [goods::Spawn::spawn
] takes [maybe_sync::BoxFuture
] that is
a sendable boxed future when "sync" feature is enabled,
allowing using multithreaded future executors.
And without "sync" feature [maybe_sync::BoxFuture
] is
a non-sendable boxed future and only then [FetchSource
] exists.
Similar story with ECS crates.
Most of them require that components are [Send
] + [Sync
]
so systems can access them from any thread.
This makes it impossible to have types from [web-sys
] in components.
Some small application may desire to turn off "sync" feature in their dependencies as they are singlethreaded and would rather not pay for what they don't use.
MaybeSend
] and [MaybeSync
]Marker traits [MaybeSend
] and [MaybeSync
] can be used in place of
[Send
] and [Sync
] traits in where clauses and bounds.
When "sync" feature is enabled then [MaybeSend
] is actually reexported [Send
]
and [MaybeSync
] is reexported [Sync
] trait.
Thus allowing types with those bounds to be sent or shared across threads.
When "sync" feature is not enabled then [MaybeSend
] and [MaybeSync
] are empty
traits implemented for all types and when used as bounds permit types that
does not satisfy [Send
] or [Sync
] bounds.
This makes it impossible to forget enable "sync" feature and accidentally send
!Send
value to another thread.
Function that uncodintionally send value to another thread
should not use [MaybeSend
] bound, but an actual [Send
].
Type alias for boxed future. Sendable if "sync" feature is enabled.
It is designed to be used as return type from trait functions
where trait implementations that produce non-sendable futures
exist only when "sync" feature is not enabled.
It can be used as function argument type when [MaybeSend
] bound is placed.
Type alias to [alloc::rc::Rc
] when "sync" feature is not enabled, or
[alloc::sync::Arc
] when "sync" feature is enabled. Serves for optimization
purposes for crates that already use [maybe-sync
] crate.
Type alias to [parking_lot::Mutex
] when "sync" feature is enabled, or
thin wrapper arond [core::cell::RefCell
] otherwise. Serves for optimization
purposes for crates that already use [maybe-sync
] crate.
This repository is licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.