1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//! A procedural macro for Rust that allows you to ensure that functions (e.g.
//! unit tests) are not running at the same time.
//!
//! This is achieved by executing the provided expression (a mutex lock,
//! for instance) the beginning of the annotated function and holding on to
//! the returned value (for instance, the lock guard), such that the lock is
//! released when the function returns (or panics).
//!
//! This is useful to inject locks into functions that altered by other macros,
//! like `tokio::test`, and where you can't inject your lock expression by other
//! means.
//!
//! Macros are applied from top to bottom, when using with `tokio:test` and
//! similar macros, be sure to insert the `nonparallel` call **last**.
//! This will wrap the entire runtime with the lock.
//! If you insert `nonparallel` above the `tokio::test`, the lock will be
//! executed inside the runtime, which means the runtime will shutdown after
//! the lock is released, and may lead to things you meant to be under mutex to
//! run outside of mutex until the runtime actually shuts down.
//!
//! ## Usage
//!
//! ```rust
//! use tokio::sync::Mutex;
//! use nonparallelex::nonparallel;
//!
//! // Create two locks
//! static MUT_A: Mutex<()> = Mutex::const_new(());
//! static MUT_B: Mutex<()> = Mutex::const_new(());
//!
//! // Mutually exclude parallel runs of functions using those two locks.
//!
//! #[tokio::test]
//! #[nonparallel(MUT_A.blocking_lock())]
//! async fn function_a1() {
//! // This will not run in parallel to function_a2.
//! }
//!
//! #[tokio::test]
//! #[nonparallel(MUT_A.blocking_lock())]
//! async fn function_a2() {
//! // This will not run in parallel to function_a1.
//! }
//!
//! #[tokio::test]
//! #[nonparallel(MUT_B.blocking_lock())]
//! async fn function_b() {
//! // This may run in parallel to function_a*.
//! }
//! ```
extern crate proc_macro;
use TokenStream;
use ;
use ;
use ;