ssize_t hbm::communication::SocketNonblocking::sendBlocks(const dataBlocks_t &blocks) { std::vector < iovec > iovs(6); // reserve a reasonable number of entries! size_t completeLength = 0; iovec newIovec; for(dataBlocks_t::const_iterator iter=blocks.begin(); iter!=blocks.end(); ++iter) { const dataBlock_t& item = *iter; newIovec.iov_base = const_cast < void* > (item.pData); newIovec.iov_len = item.size; iovs.push_back(newIovec); completeLength += item.size; } ssize_t retVal = writev(m_fd, &iovs[0], iovs.size()); if (retVal==0) { return retVal; } else if (retVal==-1) { if((errno!=EWOULDBLOCK) && (errno!=EAGAIN) && (errno!=EINTR) ) { return retVal; } } size_t bytesWritten = retVal; if(bytesWritten==completeLength) { // we are done! return bytesWritten; } else { size_t blockSum = 0; for(size_t index=0; index<iovs.size(); ++index) { blockSum += iovs[index].iov_len; if(bytesWritten<blockSum) { // this block was not send completely size_t bytesRemaining = blockSum - bytesWritten; size_t start = iovs[index].iov_len-bytesRemaining; retVal = sendBlock(static_cast < unsigned char* > (iovs[index].iov_base)+start, bytesRemaining, false); if(retVal>0) { bytesWritten += retVal; } else { return -1; } } } } return bytesWritten; }
static void CopyOrDupFiles(const char *dir, bool copy, int nfiles) { const int N = 4096; std::vector<struct tc_extent_pair> pairs(nfiles); std::vector<struct tc_iovec> iovs(nfiles); std::vector<struct tc_iovec> read_iovs(nfiles); std::vector<std::string> src_paths(nfiles); std::vector<std::string> dst_paths(nfiles); char buf[PATH_MAX]; EXPECT_TRUE(tc_rm_recursive(dir)); EXPECT_OK(tc_ensure_dir(dir, 0755, NULL)); for (int i = 0; i < nfiles; ++i) { src_paths[i].assign( buf, snprintf(buf, PATH_MAX, "%s/src-%d.txt", dir, i)); dst_paths[i].assign( buf, snprintf(buf, PATH_MAX, "%s/dst-%d.txt", dir, i)); tc_fill_extent_pair(&pairs[i], src_paths[i].c_str(), 0, dst_paths[i].c_str(), 0, N); tc_iov4creation(&iovs[i], pairs[i].src_path, N, getRandomBytes(N)); EXPECT_NOTNULL(iovs[i].data); tc_iov2path(&read_iovs[i], pairs[i].dst_path, 0, N, (char *)malloc(N)); EXPECT_NOTNULL(read_iovs[i].data); } EXPECT_OK(tc_writev(iovs.data(), nfiles, false)); // copy or move files if (copy) { EXPECT_OK(tc_copyv(pairs.data(), nfiles, false)); } else { EXPECT_OK(tc_dupv(pairs.data(), nfiles, false)); } EXPECT_OK(tc_readv(read_iovs.data(), nfiles, false)); compare_content(iovs.data(), read_iovs.data(), nfiles); for (int i = 0; i < nfiles; ++i) { free(iovs[i].data); free(read_iovs[i].data); } }