- 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;
+ void* whereto = const_cast<void*>(message);
+ size_t todo = size;
+ if (bufsize > 0) {
+ XBT_DEBUG("%d %zu bytes (of %zu expected) are already in buffer", getpid(), bufsize, size);
+ if (bufsize >= size) {
+ copied = size;
+ memcpy(whereto, buffer_.data(), size);
+ memcpy(static_cast<void*>(buffer_.data()), buffer_.data() + size, bufsize - size);
+ buffer_.resize(bufsize - size);
+ todo = 0;
+ } else {
+ copied = bufsize;
+ memcpy(whereto, buffer_.data(), bufsize);
+ buffer_.clear();
+ todo -= bufsize;
+ whereto = static_cast<char*>(whereto) + bufsize;
+ }
+ }
+ 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 %d; Got %d from buffer and %d from network", getpid(), (int)size, (int)copied, (int)res);
+ res += copied;