- ssize_t res = recv(this->socket_, message, size, 0);
- xbt_assert(res != -1, "Channel::receive failure: %s", strerror(errno));
+ size_t bufsize = buffer_.size();
+ ssize_t copied = 0;
+ auto* whereto = static_cast<char*>(message);
+ size_t todo = size;
+ if (bufsize > 0) {
+ XBT_DEBUG("%d %zu bytes (of %zu expected) are already in buffer", getpid(), bufsize, size);
+ copied = std::min(size, bufsize);
+ std::copy_n(begin(buffer_), copied, whereto);
+ buffer_.erase(begin(buffer_), begin(buffer_) + copied);
+ todo -= copied;
+ whereto += copied;
+ }
+ ssize_t res = 0;
+ if (todo > 0) {
+ errno = 0;
+ res = recv(this->socket_, whereto, todo, flags);
+ xbt_assert(res != -1 || errno == EAGAIN, "Channel::receive failure: %s", strerror(errno));
+ if (res == -1) {
+ res = 0;
+ }
+ }
+ XBT_DEBUG("%d Wanted %zu; Got %zd from buffer and %zd from network", getpid(), size, copied, res);
+ res += copied;