@@ -14,7 +14,6 @@ use ptr;
1414use option:: { Option , Some , None } ;
1515use task;
1616use unstable:: atomics:: { AtomicOption , AtomicUint , Acquire , Release , Relaxed , SeqCst } ;
17- use unstable:: finally:: Finally ;
1817use unstable:: mutex:: Mutex ;
1918use ops:: Drop ;
2019use clone:: Clone ;
@@ -295,17 +294,44 @@ impl<T> Drop for UnsafeArc<T>{
295294
296295/****************************************************************************/
297296
297+ pub struct AtomicGuard {
298+ on : bool ,
299+ }
300+
301+ impl Drop for AtomicGuard {
302+ fn drop ( & mut self ) {
303+ use rt:: task:: { Task , GreenTask , SchedTask } ;
304+ use rt:: local:: Local ;
305+
306+ if self . on {
307+ unsafe {
308+ let task_opt: Option < * mut Task > = Local :: try_unsafe_borrow ( ) ;
309+ match task_opt {
310+ Some ( t) => {
311+ match ( * t) . task_type {
312+ GreenTask ( _) => ( * t) . death . allow_deschedule ( ) ,
313+ SchedTask => { }
314+ }
315+ }
316+ None => { }
317+ }
318+ }
319+ }
320+ }
321+ }
322+
298323/**
299- * Enables a runtime assertion that no operation in the argument closure shall
300- * use scheduler operations (deschedule, recv, spawn, etc). This is for use with
301- * pthread mutexes, which may block the entire scheduler thread, rather than
302- * just one task, and is hence prone to deadlocks if mixed with descheduling.
324+ * Enables a runtime assertion that no operation while the returned guard is
325+ * live uses scheduler operations (deschedule, recv, spawn, etc). This is for
326+ * use with pthread mutexes, which may block the entire scheduler thread,
327+ * rather than just one task, and is hence prone to deadlocks if mixed with
328+ * descheduling.
303329 *
304330 * NOTE: THIS DOES NOT PROVIDE LOCKING, or any sort of critical-section
305331 * synchronization whatsoever. It only makes sense to use for CPU-local issues.
306332 */
307333// FIXME(#8140) should not be pub
308- pub unsafe fn atomically < U > ( f : || -> U ) -> U {
334+ pub unsafe fn atomic ( ) -> AtomicGuard {
309335 use rt:: task:: { Task , GreenTask , SchedTask } ;
310336 use rt:: local:: Local ;
311337
@@ -314,15 +340,19 @@ pub unsafe fn atomically<U>(f: || -> U) -> U {
314340 Some ( t) => {
315341 match ( * t) . task_type {
316342 GreenTask ( _) => {
317- ( || {
318- ( * t ) . death . inhibit_deschedule ( ) ;
319- f ( )
320- } ) . finally ( || ( * t ) . death . allow_deschedule ( ) )
343+ ( * t ) . death . inhibit_deschedule ( ) ;
344+ return AtomicGuard {
345+ on : true ,
346+ } ;
321347 }
322- SchedTask => f ( )
348+ SchedTask => { }
323349 }
324350 }
325- None => f ( )
351+ None => { }
352+ }
353+
354+ AtomicGuard {
355+ on : false ,
326356 }
327357}
328358
@@ -481,7 +511,7 @@ mod tests {
481511 use comm;
482512 use option:: * ;
483513 use prelude:: * ;
484- use super :: { Exclusive , UnsafeArc , atomically } ;
514+ use super :: { Exclusive , UnsafeArc , atomic } ;
485515 use task;
486516 use mem:: size_of;
487517
@@ -493,10 +523,10 @@ mod tests {
493523 }
494524
495525 #[ test]
496- fn test_atomically ( ) {
526+ fn test_atomic ( ) {
497527 // NB. The whole runtime will abort on an 'atomic-sleep' violation,
498528 // so we can't really test for the converse behaviour.
499- unsafe { atomically ( || ( ) ) } task :: deschedule ( ) ; // oughtn't fail
529+ unsafe { let _ = atomic ( ) ; } // oughtn't fail
500530 }
501531
502532 #[ test]
0 commit comments