     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61

    // Copyright 2017 Amanieu d'Antras
    //
    // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
    // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
    // http://opensource.org/licenses/MIT>, at your option. This file may not be
    // copied, modified, or distributed except according to those terms.

    use std::collections::BinaryHeap;
    use std::sync::Mutex;
    use std::usize;

    // Thread ID manager which allocates thread IDs. It attempts to aggressively
    // reuse thread IDs where possible to avoid cases where a ThreadLocal grows
    // indefinitely when it is used by many short-lived threads.
    struct ThreadIdManager {
        limit: usize,
        free_list: BinaryHeap<usize>,
    }
    impl ThreadIdManager {
        fn new() -> ThreadIdManager {
            ThreadIdManager {
                limit: usize::MAX,
                free_list: BinaryHeap::new(),
            }
        }
        fn alloc(&mut self) -> usize {
            if let Some(id) = self.free_list.pop() {
                id
            } else {
                let id = self.limit;
                self.limit = self.limit.checked_sub(1).expect("Ran out of thread IDs");
                id
            }
        }
        fn free(&mut self, id: usize) {
            self.free_list.push(id);
        }
    }
    lazy_static! {
        static ref THREAD_ID_MANAGER: Mutex<ThreadIdManager> = Mutex::new(ThreadIdManager::new());
    }

    // Non-zero integer which is unique to the current thread while it is running.
    // A thread ID may be reused after a thread exits.
    struct ThreadId(usize);
    impl ThreadId {
        fn new() -> ThreadId {
            ThreadId(THREAD_ID_MANAGER.lock().unwrap().alloc())
        }
    }
    impl Drop for ThreadId {
        fn drop(&mut self) {
            THREAD_ID_MANAGER.lock().unwrap().free(self.0);
        }
    }
    thread_local!(static THREAD_ID: ThreadId = ThreadId::new());

    /// Returns a non-zero ID for the current thread
    pub fn get() -> usize {
        THREAD_ID.with(|x| x.0)
    }

# Help

## Keyboard Shortcuts

`?`
  Show this help dialog
`S`
  Focus the search field
`↑`
  Move up in search results
`↓`
  Move down in search results
`↹`
  Switch tab
`⏎`
  Go to active search result
`+`
  Expand all sections
`-`
  Collapse all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g., `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g., `vec -> usize` or `* -> vec`)

Search multiple things at once by splitting your query with comma (e.g., `str,u8` or `String,struct:Vec,test`)