@@ -37,29 +37,37 @@ POSSIBILITY OF SUCH DAMAGE.
37
37
#include " libtorrent/alert.hpp"
38
38
#include " libtorrent/heterogeneous_queue.hpp"
39
39
#include " libtorrent/stack_allocator.hpp"
40
+ #include " libtorrent/alert_types.hpp" // for num_alert_types
40
41
41
42
#include < functional>
42
43
#include < list>
43
44
#include < utility> // for std::forward
44
45
#include < mutex>
45
46
#include < condition_variable>
46
47
#include < atomic>
48
+ #include < bitset>
47
49
48
50
namespace libtorrent {
49
51
50
52
#ifndef TORRENT_DISABLE_EXTENSIONS
51
53
struct plugin ;
52
54
#endif
53
55
56
+ // this bitset is used to indicate which alert types have been dropped since
57
+ // last queried.
58
+ using dropped_alerts_t = std::bitset<num_alert_types>;
59
+
54
60
class TORRENT_EXTRA_EXPORT alert_manager
55
61
{
56
62
public:
57
63
alert_manager (int queue_limit
58
64
, alert_category_t alert_mask = alert::error_notification);
59
65
~alert_manager ();
60
66
67
+ dropped_alerts_t dropped_alerts ();
68
+
61
69
template <class T , typename ... Args>
62
- void emplace_alert (Args&&... args)
70
+ void emplace_alert (Args&&... args) try
63
71
{
64
72
std::unique_lock<std::mutex> lock (m_mutex);
65
73
@@ -69,12 +77,8 @@ namespace libtorrent {
69
77
if (m_alerts[m_generation].size () >= m_queue_size_limit
70
78
* (1 + T::priority))
71
79
{
72
- // if (T::priority > 0)
73
- // {
74
- // TODO: there should be a way for the client to detect that an
75
- // alert was dropped. Maybe add a flag to each m_alerts
76
- // generation
77
- // }
80
+ // record that we dropped an alert of this type
81
+ m_dropped.set (T::alert_type);
78
82
return ;
79
83
}
80
84
@@ -83,6 +87,12 @@ namespace libtorrent {
83
87
84
88
maybe_notify (&alert, lock);
85
89
}
90
+ catch (std::bad_alloc const &)
91
+ {
92
+ // record that we dropped an alert of this type
93
+ std::unique_lock<std::mutex> lock (m_mutex);
94
+ m_dropped.set (T::alert_type);
95
+ }
86
96
87
97
bool pending () const ;
88
98
void get_all (std::vector<alert*>& alerts);
@@ -105,12 +115,12 @@ namespace libtorrent {
105
115
m_alert_mask = m;
106
116
}
107
117
108
- alert_category_t alert_mask () const
118
+ alert_category_t alert_mask () const noexcept
109
119
{
110
120
return m_alert_mask;
111
121
}
112
122
113
- int alert_queue_size_limit () const { return m_queue_size_limit; }
123
+ int alert_queue_size_limit () const noexcept { return m_queue_size_limit; }
114
124
int set_alert_queue_size_limit (int queue_size_limit_);
115
125
116
126
void set_notify_function (std::function<void ()> const & fun);
@@ -133,6 +143,12 @@ namespace libtorrent {
133
143
std::atomic<alert_category_t > m_alert_mask;
134
144
int m_queue_size_limit;
135
145
146
+ // a bitfield where each bit represents an alert type. Every time we drop
147
+ // an alert (because the queue is full or of some other error) we set the
148
+ // corresponding bit in this mask, to communicate to the client that it
149
+ // may have missed an update.
150
+ dropped_alerts_t m_dropped;
151
+
136
152
// this function (if set) is called whenever the number of alerts in
137
153
// the alert queue goes from 0 to 1. The client is expected to wake up
138
154
// its main message loop for it to poll for alerts (using get_alerts()).
0 commit comments