Skip to content

Commit

Permalink
collectd: avoid using an exception as end-of-packet indicator
Browse files Browse the repository at this point in the history
Collectd uses an exception to signal that the buffer space in the packet
is exhausted and a new packet needs to be started.  This violates the
"exceptions are for exceptional conditions" guideline, but more practically,
makes it hard to use the gdb "catch throw" command to trap exceptions.

Fix by using a data member to store the overflow condition instead.
  • Loading branch information
avikivity committed May 11, 2015
1 parent 0e23702 commit 4cea444
Showing 1 changed file with 30 additions and 19 deletions.
49 changes: 30 additions & 19 deletions core/scollectd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ class impl {

buffer_type _buf;
mark_type _pos;
bool _overflow = false;

std::unordered_map<uint16_t, std::string> _cache;

Expand All @@ -209,8 +210,12 @@ class impl {
mark_type mark() const {
return _pos;
}
bool overflow() const {
return _overflow;
}
void reset(mark_type m) {
_pos = m;
_overflow = false;
}
size_t size() const {
return std::distance(_buf.begin(), const_mark_type(_pos));
Expand All @@ -221,24 +226,30 @@ class impl {
void clear() {
reset(_buf.begin());
_cache.clear();
_overflow = false;
}
const char * data() const {
return &_buf.at(0);
}
char * data() {
return &_buf.at(0);
}
void check(size_t sz) const {
size_t av = std::distance(const_mark_type(_pos), _buf.end());
if (av < sz) {
throw std::length_error("buffer overflow");
}
cpwriter& check(size_t sz) {
size_t av = std::distance(_pos, _buf.end());
_overflow |= av < sz;
return *this;
}
explicit operator bool() const {
return !_overflow;
}
bool operator!() const {
return !operator bool();
}

template<typename _Iter>
cpwriter & write(_Iter s, _Iter e) {
check(std::distance(s, e));
_pos = std::copy(s, e, _pos);
if (check(std::distance(s, e))) {
_pos = std::copy(s, e, _pos);
}
return *this;
}
template<typename T>
Expand Down Expand Up @@ -279,14 +290,15 @@ class impl {
cpwriter & put(part_type type, const value_list & v) {
auto s = v.size();
auto sz = 6 + s + s * sizeof(uint64_t);
check(sz);
write(uint16_t(type));
write(uint16_t(sz));
write(uint16_t(s));
v.types(reinterpret_cast<data_type *>(&(*_pos)));
_pos += s;
v.values(reinterpret_cast<net::packed<uint64_t> *>(&(*_pos)));
_pos += s * sizeof(uint64_t);
if (check(sz)) {
write(uint16_t(type));
write(uint16_t(sz));
write(uint16_t(s));
v.types(reinterpret_cast<data_type *>(&(*_pos)));
_pos += s;
v.values(reinterpret_cast<net::packed<uint64_t> *>(&(*_pos)));
_pos += s * sizeof(uint64_t);
}
return *this;
}
cpwriter & put(const std::string & host, const type_instance_id & id) {
Expand Down Expand Up @@ -353,9 +365,8 @@ class impl {
continue;
}
auto m = out.mark();
try {
out.put(_host, _period, i->first, *i->second);
} catch (std::length_error &) {
out.put(_host, _period, i->first, *i->second);
if (!out) {
out.reset(m);
break;
}
Expand Down

0 comments on commit 4cea444

Please sign in to comment.