aboutsummaryrefslogtreecommitdiff
path: root/src/server/resources.cc
blob: 9b4a1b852bb42191d979ae5976d898a242be2ba9 (plain)
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
#include "resources.hh"

namespace server {
namespace resources {

void init() noexcept { server::database::init(); }

// NOT THREAD SAFE! Use get_resources_lock!
static client_map& get_client_map() noexcept {
    static client_map ret{};
    return ret;
}

static chunk_map& get_chunk_map() noexcept {
    static chunk_map ret{314'159, shared::world::chunk::hash,
                         shared::world::chunk::equal};
    return ret;
}

static pool_t& get_pool() noexcept {
    static pool_t ret{};
    return ret;
}

static resources& get_resources() noexcept {
    static struct resources ret = {.clients = get_client_map(),
                                   .chunks = get_chunk_map(),
                                   .pool = get_pool()};
    return ret;
}

low_priority_lock<resources> get_resources_lock() noexcept {
    return low_priority_lock<resources>{get_resources()};
}
high_priority_lock<resources> get_resources_lock_immediate() noexcept {
    return high_priority_lock<resources>{get_resources()};
}

void quit() noexcept {
    const auto sleep = []() {
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    };

    // we recursively post in some cases, so this check is necessary.
    while (!get_resources_lock()->clients.empty()) {
        sleep();
        continue;
    }

    while (!get_resources_lock()->chunks.empty()) {
        sleep();
        continue;
    }

    get_resources_lock()->pool.join();
    server::database::quit();
}

} // namespace resources
} // namespace server