@@ -63,6 +63,81 @@ pub fn run_in_newsched_task_core(f: ~fn()) {
6363    sched. bootstrap ( task) ; 
6464} 
6565
66+ #[ cfg( target_os="macos" ) ]  
67+ #[ allow( non_camel_case_types) ]  
68+ mod  darwin_fd_limit { 
69+     /*! 
70+      * darwin_fd_limit exists to work around an issue where launchctl on Mac OS X defaults the 
71+      * rlimit maxfiles to 256/unlimited. The default soft limit of 256 ends up being far too low 
72+      * for our multithreaded scheduler testing, depending on the number of cores available. 
73+      * 
74+      * This fixes issue #7772. 
75+      */ 
76+ 
77+     use  libc; 
78+     type  rlim_t  = libc:: uint64_t ; 
79+     struct  rlimit  { 
80+         rlim_cur :  rlim_t , 
81+         rlim_max :  rlim_t 
82+     } 
83+     #[ nolink]  
84+     extern  { 
85+         // name probably doesn't need to be mut, but the C function doesn't specify const 
86+         fn  sysctl ( name :  * mut  libc:: c_int ,  namelen :  libc:: c_uint , 
87+                   oldp :  * mut  libc:: c_void ,  oldlenp :  * mut  libc:: size_t , 
88+                   newp :  * mut  libc:: c_void ,  newlen :  libc:: size_t )  -> libc:: c_int ; 
89+         fn  getrlimit ( resource :  libc:: c_int ,  rlp :  * mut  rlimit )  -> libc:: c_int ; 
90+         fn  setrlimit ( resource :  libc:: c_int ,  rlp :  * rlimit )  -> libc:: c_int ; 
91+     } 
92+     static  CTL_KERN :  libc:: c_int  = 1 ; 
93+     static  KERN_MAXFILESPERPROC :  libc:: c_int  = 29 ; 
94+     static  RLIMIT_NOFILE :  libc:: c_int  = 8 ; 
95+ 
96+     pub  unsafe  fn  raise_fd_limit ( )  { 
97+         // The strategy here is to fetch the current resource limits, read the kern.maxfilesperproc 
98+         // sysctl value, and bump the soft resource limit for maxfiles up to the sysctl value. 
99+         use  ptr:: { to_unsafe_ptr,  to_mut_unsafe_ptr,  mut_null} ; 
100+         use  sys:: size_of_val; 
101+         use  os:: last_os_error; 
102+ 
103+         // Fetch the kern.maxfilesperproc value 
104+         let  mut  mib:  [ libc:: c_int ,  ..2 ]  = [ CTL_KERN ,  KERN_MAXFILESPERPROC ] ; 
105+         let  mut  maxfiles:  libc:: c_int  = 0 ; 
106+         let  mut  size:  libc:: size_t  = size_of_val ( & maxfiles)  as  libc:: size_t ; 
107+         if  sysctl ( to_mut_unsafe_ptr ( & mut  mib[ 0 ] ) ,  2 , 
108+                   to_mut_unsafe_ptr ( & mut  maxfiles)  as  * mut  libc:: c_void , 
109+                   to_mut_unsafe_ptr ( & mut  size) , 
110+                   mut_null ( ) ,  0 )  != 0  { 
111+             let  err = last_os_error ( ) ; 
112+             error ! ( "raise_fd_limit: error calling sysctl: %s" ,  err) ; 
113+             return ; 
114+         } 
115+ 
116+         // Fetch the current resource limits 
117+         let  mut  rlim = rlimit { rlim_cur :  0 ,  rlim_max :  0 } ; 
118+         if  getrlimit ( RLIMIT_NOFILE ,  to_mut_unsafe_ptr ( & mut  rlim) )  != 0  { 
119+             let  err = last_os_error ( ) ; 
120+             error ! ( "raise_fd_limit: error calling getrlimit: %s" ,  err) ; 
121+             return ; 
122+         } 
123+ 
124+         // Bump the soft limit to the smaller of kern.maxfilesperproc and the hard limit 
125+         rlim. rlim_cur  = :: cmp:: min ( maxfiles as  rlim_t ,  rlim. rlim_max ) ; 
126+ 
127+         // Set our newly-increased resource limit 
128+         if  setrlimit ( RLIMIT_NOFILE ,  to_unsafe_ptr ( & rlim) )  != 0  { 
129+             let  err = last_os_error ( ) ; 
130+             error ! ( "raise_fd_limit: error calling setrlimit: %s" ,  err) ; 
131+             return ; 
132+         } 
133+     } 
134+ } 
135+ 
136+ #[ cfg( not( target_os="macos" ) ) ]  
137+ mod  darwin_fd_limit { 
138+     pub  unsafe  fn  raise_fd_limit ( )  { } 
139+ } 
140+ 
66141/// Create more than one scheduler and run a function in a task 
67142/// in one of the schedulers. The schedulers will stay alive 
68143/// until the function `f` returns. 
@@ -72,6 +147,9 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
72147    use  rt:: sched:: Shutdown ; 
73148    use  rt:: util; 
74149
150+     // Bump the fd limit on OS X. See darwin_fd_limit for an explanation. 
151+     unsafe  {  darwin_fd_limit:: raise_fd_limit ( )  } 
152+ 
75153    let  f = Cell :: new ( f) ; 
76154
77155    do  run_in_bare_thread { 
0 commit comments