-
Notifications
You must be signed in to change notification settings - Fork 21
/
buffer_pool.cpp
95 lines (79 loc) · 1.84 KB
/
buffer_pool.cpp
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "buffer_pool.hpp"
namespace ezio
{
void watermark_callback(std::vector<std::weak_ptr<libtorrent::disk_observer>> const &cbs)
{
for (auto const &i : cbs) {
std::shared_ptr<libtorrent::disk_observer> o = i.lock();
if (o) {
o->on_disk();
}
}
}
buffer_pool::buffer_pool(libtorrent::io_context &ioc) :
m_ios(ioc),
m_size(0),
m_exceeded_max_size(false)
{
}
buffer_pool::~buffer_pool()
{
}
char *buffer_pool::allocate_buffer_impl(std::unique_lock<std::mutex> &l)
{
// no memory
if (m_size >= BUFFER_COUNT) {
m_exceeded_max_size = true;
return nullptr;
}
// reach high watermak, but still has some buffer to use
if (m_size > HIGH_WATERMARK) {
m_exceeded_max_size = true;
}
char *buf = (char*)malloc(DEFAULT_BLOCK_SIZE);
if (!buf) {
m_exceeded_max_size = true;
return nullptr;
}
m_size++;
return buf;
}
char *buffer_pool::allocate_buffer()
{
std::unique_lock<std::mutex> l(m_pool_mutex);
return allocate_buffer_impl(l);
}
char *buffer_pool::allocate_buffer(bool &exceeded, std::shared_ptr<libtorrent::disk_observer> o)
{
std::unique_lock<std::mutex> l(m_pool_mutex);
char *buf = allocate_buffer_impl(l);
if (m_exceeded_max_size) {
exceeded = true;
if (o) {
m_observers.push_back(o);
}
}
return buf;
}
void buffer_pool::free_disk_buffer(char *buf)
{
std::unique_lock<std::mutex> l(m_pool_mutex);
free(buf);
m_size--;
check_buffer_level(l);
}
void buffer_pool::check_buffer_level(std::unique_lock<std::mutex> &l)
{
if (!m_exceeded_max_size || m_size > LOW_WATERMARK) {
// still high usgae
return;
}
// lower than LOW_WATERMARKi, reopen
m_exceeded_max_size = false;
std::vector<std::weak_ptr<libtorrent::disk_observer>> cbs;
m_observers.swap(cbs);
// we could unlock mutex to let others allocate buffer
l.unlock();
post(m_ios, std::bind(&watermark_callback, std::move(cbs)));
}
} // namespace ezio