summaryrefslogtreecommitdiff
path: root/src/protocols.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/protocols.cc')
-rw-r--r--src/protocols.cc22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/protocols.cc b/src/protocols.cc
index 31b3bfd..df7353a 100644
--- a/src/protocols.cc
+++ b/src/protocols.cc
@@ -66,7 +66,7 @@ public:
entry.data_ = data;
entry.size_ = size;
- reschedule_with_lock();
+ if (size) reschedule_with_lock();
}
void update(size_t id, void const* data, size_t size) override {
@@ -87,6 +87,15 @@ public:
return;
}
}
+
+ for (auto const& active : active_) {
+ if (active == id) {
+ invalidate_.emplace(id);
+ return;
+ }
+ }
+
+ if (old == 0) reschedule_with_lock();
}
void remove(size_t id) override {
@@ -268,7 +277,7 @@ private:
void reschedule_with_lock() {
if (cache_.size() < cache_size_) {
- size_t want = cache_.size() - cache_size_;
+ size_t want = cache_size_ - cache_.size();
size_t queued = active_.size() + queue_.size();
if (want < queued) {
want = 0;
@@ -382,6 +391,14 @@ private:
std::unique_ptr<Protocol::Match>&& match,
std::unique_ptr<AttributedText>&& text) {
active_.erase(std::find(active_.begin(), active_.end(), id));
+ if (invalidate_.erase(id)) {
+ if (wanted_ == id) {
+ queue_.emplace_front(id, size, std::move(match), std::move(text));
+ } else {
+ queue_.emplace_back(id, size, std::move(match), std::move(text));
+ }
+ return;
+ }
while (cache_.size() >= cache_size_) {
auto oldest = cache_.end();
for (auto it = cache_.begin(); it != cache_.end(); ++it) {
@@ -457,6 +474,7 @@ private:
std::vector<CacheEntry> cache_;
std::vector<size_t> active_;
std::deque<QueueEntry> queue_;
+ std::unordered_set<size_t> invalidate_;
std::deque<ContentEntry> content_done_;
std::deque<ContentEntry> content_queue_;