]> git.proxmox.com Git - rustc.git/blob - src/libstd/sys/windows/mutex.rs
29e370698ad744b727f4c202c5d333a9ee6ea193
[rustc.git] / src / libstd / sys / windows / mutex.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use prelude::v1::*;
12
13 use cell::UnsafeCell;
14 use sys::sync as ffi;
15 use mem;
16
17 pub struct Mutex { inner: UnsafeCell<ffi::SRWLOCK> }
18
19 unsafe impl Send for Mutex {}
20 unsafe impl Sync for Mutex {}
21
22 #[inline]
23 pub unsafe fn raw(m: &Mutex) -> ffi::PSRWLOCK {
24 m.inner.get()
25 }
26
27 // So you might be asking why we're using SRWLock instead of CriticalSection?
28 //
29 // 1. SRWLock is several times faster than CriticalSection according to
30 // benchmarks performed on both Windows 8 and Windows 7.
31 //
32 // 2. CriticalSection allows recursive locking while SRWLock deadlocks. The Unix
33 // implementation deadlocks so consistency is preferred. See #19962 for more
34 // details.
35 //
36 // 3. While CriticalSection is fair and SRWLock is not, the current Rust policy
37 // is there there are no guarantees of fairness.
38
39 impl Mutex {
40 pub const fn new() -> Mutex {
41 Mutex { inner: UnsafeCell::new(ffi::SRWLOCK_INIT) }
42 }
43 #[inline]
44 pub unsafe fn lock(&self) {
45 ffi::AcquireSRWLockExclusive(self.inner.get())
46 }
47 #[inline]
48 pub unsafe fn try_lock(&self) -> bool {
49 ffi::TryAcquireSRWLockExclusive(self.inner.get()) != 0
50 }
51 #[inline]
52 pub unsafe fn unlock(&self) {
53 ffi::ReleaseSRWLockExclusive(self.inner.get())
54 }
55 #[inline]
56 pub unsafe fn destroy(&self) {
57 // ...
58 }
59 }
60
61 pub struct ReentrantMutex { inner: UnsafeCell<ffi::CRITICAL_SECTION> }
62
63 unsafe impl Send for ReentrantMutex {}
64 unsafe impl Sync for ReentrantMutex {}
65
66 impl ReentrantMutex {
67 pub unsafe fn uninitialized() -> ReentrantMutex {
68 mem::uninitialized()
69 }
70
71 pub unsafe fn init(&mut self) {
72 ffi::InitializeCriticalSection(self.inner.get());
73 }
74
75 pub unsafe fn lock(&self) {
76 ffi::EnterCriticalSection(self.inner.get());
77 }
78
79 #[inline]
80 pub unsafe fn try_lock(&self) -> bool {
81 ffi::TryEnterCriticalSection(self.inner.get()) != 0
82 }
83
84 pub unsafe fn unlock(&self) {
85 ffi::LeaveCriticalSection(self.inner.get());
86 }
87
88 pub unsafe fn destroy(&self) {
89 ffi::DeleteCriticalSection(self.inner.get());
90 }
91 }