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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! Threading support (§57, §93, §85 Phase 1).
//!
//! Thread-local state, concurrent parsing, concurrent transformation,
//! shared immutable dictionaries, callback isolation.
//!
//! # UPSTREAM-PARITY
//!
//! libxml2's threading support provides:
//!
//! - `xmlInitThreads()` / `xmlCleanupThreads()` — lifecycle
//! - `xmlLockLibrary()` / `xmlUnlockLibrary()` — global lock
//! - Thread-local storage for error state and parser contexts
//!
//! In modern libxml2 (2.12+), threading is initialized automatically
//! by `xmlInitParser`. The explicit thread functions exist for backward
//! compatibility.
//!
//! In Rust, we use standard thread-safe primitives and `thread_local!`
//! for thread-local storage. The global lock is a no-op since Rust's
//! type system prevents data races at compile time.
//!
//! # Phase 1 status
//!
//! Complete — all threading support is implemented.
use ;
use c_int;
/// Whether threading has been initialized.
static THREADS_INITIALIZED: AtomicBool = new;
/// Initialize threading support.
///
/// # UPSTREAM-PARITY
///
/// ```c
/// int xmlInitThreads(void);
/// ```
///
/// Returns 0 on success. In modern libxml2, this is called automatically
/// by `xmlInitParser`.
/// Clean up threading support.
///
/// # UPSTREAM-PARITY
///
/// ```c
/// void xmlCleanupThreads(void);
/// ```
/// Check whether threading has been initialized.
/// Lock the library (global mutex).
///
/// # UPSTREAM-PARITY
///
/// ```c
/// void xmlLockLibrary(void);
/// ```
///
/// In upstream libxml2, this locks a global mutex. In Rust, this is
/// a no-op because Rust's type system prevents data races. However,
/// for FFI safety with C callers that may manipulate shared state,
/// a real mutex would be needed. This will be enhanced in Phase 2+.
/// Unlock the library.
///
/// # UPSTREAM-PARITY
///
/// ```c
/// void xmlUnlockLibrary(void);
/// ```
/// Get the number of active threads (for compatibility).
///
/// Returns the number of active threads, or 0 if unknown.
/// This is a compatibility stub — upstream doesn't expose this directly.
// ═══════════════════════════════════════════════════════════════════════════════
// Tests
// ═══════════════════════════════════════════════════════════════════════════════