@@ -166,9 +166,10 @@ impl Drop for Thread {
166166 not( target_os = "netbsd" ) ,
167167 not( target_os = "openbsd" ) ) ) ]
168168pub mod guard {
169- pub unsafe fn current ( ) -> usize { 0 }
170- pub unsafe fn main ( ) -> usize { 0 }
171- pub unsafe fn init ( ) { }
169+ use prelude:: v1:: * ;
170+
171+ pub unsafe fn current ( ) -> Option < usize > { None }
172+ pub unsafe fn init ( ) -> Option < usize > { None }
172173}
173174
174175
@@ -179,6 +180,8 @@ pub mod guard {
179180 target_os = "openbsd" ) ) ]
180181#[ allow( unused_imports) ]
181182pub mod guard {
183+ use prelude:: v1:: * ;
184+
182185 use libc:: { self , pthread_t} ;
183186 use libc:: funcs:: posix88:: mman:: mmap;
184187 use libc:: consts:: os:: posix88:: { PROT_NONE ,
@@ -191,31 +194,38 @@ pub mod guard {
191194 use super :: { pthread_self, pthread_attr_destroy} ;
192195 use sys:: os;
193196
194- // These are initialized in init() and only read from after
195- static mut GUARD_PAGE : usize = 0 ;
196-
197197 #[ cfg( any( target_os = "macos" ,
198198 target_os = "bitrig" ,
199199 target_os = "netbsd" ,
200200 target_os = "openbsd" ) ) ]
201- unsafe fn get_stack_start ( ) -> * mut libc:: c_void {
202- current ( ) as * mut libc:: c_void
201+ unsafe fn get_stack_start ( ) -> Option < * mut libc:: c_void > {
202+ current ( ) . map ( |s| s as * mut libc:: c_void )
203203 }
204204
205205 #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
206- unsafe fn get_stack_start ( ) -> * mut libc:: c_void {
206+ unsafe fn get_stack_start ( ) -> Option < * mut libc:: c_void > {
207+ use super :: pthread_attr_init;
208+
209+ let mut ret = None ;
207210 let mut attr: libc:: pthread_attr_t = mem:: zeroed ( ) ;
208- assert_eq ! ( pthread_getattr_np( pthread_self( ) , & mut attr) , 0 ) ;
209- let mut stackaddr = ptr:: null_mut ( ) ;
210- let mut stacksize = 0 ;
211- assert_eq ! ( pthread_attr_getstack( & attr, & mut stackaddr, & mut stacksize) , 0 ) ;
211+ assert_eq ! ( pthread_attr_init( & mut attr) , 0 ) ;
212+ if pthread_getattr_np ( pthread_self ( ) , & mut attr) == 0 {
213+ let mut stackaddr = ptr:: null_mut ( ) ;
214+ let mut stacksize = 0 ;
215+ assert_eq ! ( pthread_attr_getstack( & attr, & mut stackaddr,
216+ & mut stacksize) , 0 ) ;
217+ ret = Some ( stackaddr) ;
218+ }
212219 assert_eq ! ( pthread_attr_destroy( & mut attr) , 0 ) ;
213- stackaddr
220+ ret
214221 }
215222
216- pub unsafe fn init ( ) {
223+ pub unsafe fn init ( ) -> Option < usize > {
217224 let psize = os:: page_size ( ) ;
218- let mut stackaddr = get_stack_start ( ) ;
225+ let mut stackaddr = match get_stack_start ( ) {
226+ Some ( addr) => addr,
227+ None => return None ,
228+ } ;
219229
220230 // Ensure stackaddr is page aligned! A parent process might
221231 // have reset RLIMIT_STACK to be non-page aligned. The
@@ -245,25 +255,21 @@ pub mod guard {
245255
246256 let offset = if cfg ! ( target_os = "linux" ) { 2 } else { 1 } ;
247257
248- GUARD_PAGE = stackaddr as usize + offset * psize;
249- }
250-
251- pub unsafe fn main ( ) -> usize {
252- GUARD_PAGE
258+ Some ( stackaddr as usize + offset * psize)
253259 }
254260
255261 #[ cfg( target_os = "macos" ) ]
256- pub unsafe fn current ( ) -> usize {
262+ pub unsafe fn current ( ) -> Option < usize > {
257263 extern {
258264 fn pthread_get_stackaddr_np ( thread : pthread_t ) -> * mut libc:: c_void ;
259265 fn pthread_get_stacksize_np ( thread : pthread_t ) -> libc:: size_t ;
260266 }
261- ( pthread_get_stackaddr_np ( pthread_self ( ) ) as libc:: size_t -
262- pthread_get_stacksize_np ( pthread_self ( ) ) ) as usize
267+ Some ( ( pthread_get_stackaddr_np ( pthread_self ( ) ) as libc:: size_t -
268+ pthread_get_stacksize_np ( pthread_self ( ) ) ) as usize )
263269 }
264270
265271 #[ cfg( any( target_os = "openbsd" , target_os = "netbsd" , target_os = "bitrig" ) ) ]
266- pub unsafe fn current ( ) -> usize {
272+ pub unsafe fn current ( ) -> Option < usize > {
267273 #[ repr( C ) ]
268274 struct stack_t {
269275 ss_sp : * mut libc:: c_void ,
@@ -280,30 +286,36 @@ pub mod guard {
280286 assert_eq ! ( pthread_stackseg_np( pthread_self( ) , & mut current_stack) , 0 ) ;
281287
282288 let extra = if cfg ! ( target_os = "bitrig" ) { 3 } else { 1 } * os:: page_size ( ) ;
283- if pthread_main_np ( ) == 1 {
289+ Some ( if pthread_main_np ( ) == 1 {
284290 // main thread
285291 current_stack. ss_sp as usize - current_stack. ss_size as usize + extra
286292 } else {
287293 // new thread
288294 current_stack. ss_sp as usize - current_stack. ss_size as usize
289- }
295+ } )
290296 }
291297
292298 #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
293- pub unsafe fn current ( ) -> usize {
299+ pub unsafe fn current ( ) -> Option < usize > {
300+ use super :: pthread_attr_init;
301+
302+ let mut ret = None ;
294303 let mut attr: libc:: pthread_attr_t = mem:: zeroed ( ) ;
295- assert_eq ! ( pthread_getattr_np( pthread_self( ) , & mut attr) , 0 ) ;
296- let mut guardsize = 0 ;
297- assert_eq ! ( pthread_attr_getguardsize( & attr, & mut guardsize) , 0 ) ;
298- if guardsize == 0 {
299- panic ! ( "there is no guard page" ) ;
304+ assert_eq ! ( pthread_attr_init( & mut attr) , 0 ) ;
305+ if pthread_getattr_np ( pthread_self ( ) , & mut attr) == 0 {
306+ let mut guardsize = 0 ;
307+ assert_eq ! ( pthread_attr_getguardsize( & attr, & mut guardsize) , 0 ) ;
308+ if guardsize == 0 {
309+ panic ! ( "there is no guard page" ) ;
310+ }
311+ let mut stackaddr = ptr:: null_mut ( ) ;
312+ let mut size = 0 ;
313+ assert_eq ! ( pthread_attr_getstack( & attr, & mut stackaddr, & mut size) , 0 ) ;
314+
315+ ret = Some ( stackaddr as usize + guardsize as usize ) ;
300316 }
301- let mut stackaddr = ptr:: null_mut ( ) ;
302- let mut size = 0 ;
303- assert_eq ! ( pthread_attr_getstack( & attr, & mut stackaddr, & mut size) , 0 ) ;
304317 assert_eq ! ( pthread_attr_destroy( & mut attr) , 0 ) ;
305-
306- stackaddr as usize + guardsize as usize
318+ return ret
307319 }
308320
309321 #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
0 commit comments