@@ -6,6 +6,7 @@ use crate::{
6
6
zend_class_entry, zend_function_entry, zend_ini_entry_def, zend_internal_arg_info,
7
7
zend_module_entry, zend_register_ini_entries, zend_string, zend_unregister_ini_entries,
8
8
PHP_MODULE_BUILD_ID , USING_ZTS , ZEND_DEBUG , ZEND_MODULE_API_NO ,
9
+ OnUpdateBool , OnUpdateLong , OnUpdateReal , OnUpdateString ,
9
10
} ,
10
11
} ;
11
12
use once_cell:: sync:: Lazy ;
@@ -19,6 +20,9 @@ use std::{
19
20
ptr:: { null, null_mut} ,
20
21
sync:: { atomic:: AtomicPtr , Arc , Mutex , RwLock , RwLockReadGuard , RwLockWriteGuard } ,
21
22
} ;
23
+ use std:: ffi:: CStr ;
24
+ use crate :: ini:: { StrPtrBox , IniValue } ;
25
+ use std:: thread:: LocalKey ;
22
26
23
27
static GLOBAL_MODULE : Lazy < RwLock < Module > > = Lazy :: new ( Default :: default) ;
24
28
@@ -79,12 +83,18 @@ pub struct Module {
79
83
module_shutdown : Option < Box < dyn Fn ( ModuleArgs ) -> bool + Send + Sync > > ,
80
84
request_init : Option < Box < dyn Fn ( ModuleArgs ) -> bool + Send + Sync > > ,
81
85
request_shutdown : Option < Box < dyn Fn ( ModuleArgs ) -> bool + Send + Sync > > ,
82
- ini_entities : HashMap < String , IniEntity > ,
83
86
function_entities : Vec < FunctionEntity > ,
84
87
class_entities : Vec < ClassEntity > ,
85
88
}
86
89
87
90
impl Module {
91
+ thread_local ! {
92
+ static BOOL_INI_ENTITIES : RefCell <HashMap <String , IniEntity <bool >>> = Default :: default ( ) ;
93
+ static LONG_INI_ENTITIES : RefCell <HashMap <String , IniEntity <i64 >>> = Default :: default ( ) ;
94
+ static REAL_INI_ENTITIES : RefCell <HashMap <String , IniEntity <f64 >>> = Default :: default ( ) ;
95
+ static STR_INI_ENTITIES : RefCell <HashMap <String , IniEntity <StrPtrBox >>> = Default :: default ( ) ;
96
+ }
97
+
88
98
pub fn set_name ( & mut self , name : impl ToString ) {
89
99
let mut name = name. to_string ( ) ;
90
100
name. push ( '\0' ) ;
@@ -119,9 +129,52 @@ impl Module {
119
129
self . request_shutdown = Some ( Box :: new ( func) ) ;
120
130
}
121
131
122
- pub fn add_ini ( & mut self , name : impl ToString , value : impl ToString , policy : Policy ) {
123
- self . ini_entities
124
- . insert ( name. to_string ( ) , IniEntity :: new ( name, value, policy) ) ;
132
+ pub fn add_bool_ini ( & mut self , name : impl ToString , default_value : bool , policy : Policy ) {
133
+ Self :: BOOL_INI_ENTITIES . with ( |entities| {
134
+ entities. borrow_mut ( ) . insert ( name. to_string ( ) , IniEntity :: new ( name, default_value, policy) ) ;
135
+ } )
136
+ }
137
+
138
+ pub fn get_bool_ini ( name : & str ) -> Option < bool > {
139
+ Self :: BOOL_INI_ENTITIES . with ( |entities| {
140
+ entities. borrow ( ) . get ( name) . map ( |entity| * entity. value ( ) )
141
+ } )
142
+ }
143
+
144
+ pub fn add_long_ini ( & mut self , name : impl ToString , default_value : i64 , policy : Policy ) {
145
+ Self :: LONG_INI_ENTITIES . with ( |entities| {
146
+ entities. borrow_mut ( ) . insert ( name. to_string ( ) , IniEntity :: new ( name, default_value, policy) ) ;
147
+ } )
148
+ }
149
+
150
+ pub fn get_long_ini ( name : & str ) -> Option < i64 > {
151
+ Self :: LONG_INI_ENTITIES . with ( |entities| {
152
+ entities. borrow ( ) . get ( name) . map ( |entity| * entity. value ( ) )
153
+ } )
154
+ }
155
+
156
+ pub fn add_real_ini ( & mut self , name : impl ToString , default_value : f64 , policy : Policy ) {
157
+ Self :: REAL_INI_ENTITIES . with ( |entities| {
158
+ entities. borrow_mut ( ) . insert ( name. to_string ( ) , IniEntity :: new ( name, default_value, policy) ) ;
159
+ } )
160
+ }
161
+
162
+ pub fn get_real_ini ( name : & str ) -> Option < f64 > {
163
+ Self :: REAL_INI_ENTITIES . with ( |entities| {
164
+ entities. borrow ( ) . get ( name) . map ( |entity| * entity. value ( ) )
165
+ } )
166
+ }
167
+
168
+ pub fn add_str_ini ( & mut self , name : impl ToString , default_value : impl ToString , policy : Policy ) {
169
+ Self :: STR_INI_ENTITIES . with ( |entities| {
170
+ entities. borrow_mut ( ) . insert ( name. to_string ( ) , IniEntity :: new ( name, default_value, policy) ) ;
171
+ } )
172
+ }
173
+
174
+ pub fn get_str_ini ( name : & str ) -> Option < String > {
175
+ Self :: STR_INI_ENTITIES . with ( |entities| {
176
+ entities. borrow ( ) . get ( name) . and_then ( |entity| unsafe { entity. value ( ) . to_string ( ) } . ok ( ) )
177
+ } )
125
178
}
126
179
127
180
pub fn add_function ( & mut self , name : impl ToString , handler : impl Function + ' static ) {
@@ -207,17 +260,24 @@ impl Module {
207
260
Box :: into_raw ( entries. into_boxed_slice ( ) ) . cast ( )
208
261
}
209
262
210
- fn ini_entries ( & self ) -> * const zend_ini_entry_def {
263
+ unsafe fn ini_entries ( & self ) -> * const zend_ini_entry_def {
211
264
let mut entries = Vec :: new ( ) ;
212
265
213
- for ( _, ini) in & self . ini_entities {
214
- entries. push ( ini. ini_entry_def ( ) ) ;
215
- }
266
+ Self :: BOOL_INI_ENTITIES . with ( |entities| Self :: push_ini_entry ( & mut entries, & mut * entities. borrow_mut ( ) ) ) ;
267
+ Self :: LONG_INI_ENTITIES . with ( |entities| Self :: push_ini_entry ( & mut entries, & mut * entities. borrow_mut ( ) ) ) ;
268
+ Self :: REAL_INI_ENTITIES . with ( |entities| Self :: push_ini_entry ( & mut entries, & mut * entities. borrow_mut ( ) ) ) ;
269
+ Self :: STR_INI_ENTITIES . with ( |entities| Self :: push_ini_entry ( & mut entries, & mut * entities. borrow_mut ( ) ) ) ;
216
270
217
271
entries. push ( unsafe { zeroed :: < zend_ini_entry_def > ( ) } ) ;
218
272
219
273
Box :: into_raw ( entries. into_boxed_slice ( ) ) . cast ( )
220
274
}
275
+
276
+ unsafe fn push_ini_entry < T : IniValue > ( entries : & mut Vec < zend_ini_entry_def > , entities : & mut HashMap < String , IniEntity < T > > ) {
277
+ for ( _, entry) in & mut * entities. borrow_mut ( ) {
278
+ entries. push ( entry. ini_entry_def ( ) ) ;
279
+ }
280
+ }
221
281
}
222
282
223
283
pub struct ModuleArgs {
0 commit comments