| 494 | */ |
| 495 | template <class CoupledTransports> |
| 496 | void test_rw(uint32_t totalSize, |
| 497 | SizeGenerator& wSizeGenerator, |
| 498 | SizeGenerator& rSizeGenerator, |
| 499 | SizeGenerator& wChunkGenerator, |
| 500 | SizeGenerator& rChunkGenerator, |
| 501 | uint32_t maxOutstanding) { |
| 502 | CoupledTransports transports; |
| 503 | BOOST_REQUIRE(transports.in != nullptr); |
| 504 | BOOST_REQUIRE(transports.out != nullptr); |
| 505 | |
| 506 | boost::shared_array<uint8_t> wbuf = boost::shared_array<uint8_t>(new uint8_t[totalSize]); |
| 507 | boost::shared_array<uint8_t> rbuf = boost::shared_array<uint8_t>(new uint8_t[totalSize]); |
| 508 | |
| 509 | // store some data in wbuf |
| 510 | for (uint32_t n = 0; n < totalSize; ++n) { |
| 511 | wbuf[n] = (n & 0xff); |
| 512 | } |
| 513 | // clear rbuf |
| 514 | memset(rbuf.get(), 0, totalSize); |
| 515 | |
| 516 | uint32_t total_written = 0; |
| 517 | uint32_t total_read = 0; |
| 518 | while (total_read < totalSize) { |
| 519 | // Determine how large a chunk of data to write |
| 520 | uint32_t wchunk_size = wChunkGenerator.nextSize(); |
| 521 | if (wchunk_size == 0 || wchunk_size > totalSize - total_written) { |
| 522 | wchunk_size = totalSize - total_written; |
| 523 | } |
| 524 | |
| 525 | // Make sure (total_written - total_read) + wchunk_size |
| 526 | // is less than maxOutstanding |
| 527 | if (maxOutstanding > 0 && wchunk_size > maxOutstanding - (total_written - total_read)) { |
| 528 | wchunk_size = maxOutstanding - (total_written - total_read); |
| 529 | } |
| 530 | |
| 531 | // Write the chunk |
| 532 | uint32_t chunk_written = 0; |
| 533 | while (chunk_written < wchunk_size) { |
| 534 | uint32_t write_size = wSizeGenerator.nextSize(); |
| 535 | if (write_size == 0 || write_size > wchunk_size - chunk_written) { |
| 536 | write_size = wchunk_size - chunk_written; |
| 537 | } |
| 538 | |
| 539 | try { |
| 540 | transports.out->write(wbuf.get() + total_written, write_size); |
| 541 | } catch (TTransportException& te) { |
| 542 | if (te.getType() == TTransportException::TIMED_OUT) |
| 543 | break; |
| 544 | throw te; |
| 545 | } |
| 546 | chunk_written += write_size; |
| 547 | total_written += write_size; |
| 548 | } |
| 549 | |
| 550 | // Flush the data, so it will be available in the read transport |
| 551 | // Don't flush if wchunk_size is 0. (This should only happen if |
| 552 | // total_written == totalSize already, and we're only reading now.) |
| 553 | if (wchunk_size > 0) { |