--- READ --- Try to read 'len' bytes from the buffer, into the provided buffer. Returns the number of bytes read, or 0 in case of an error.
| 359 | // Try to read 'len' bytes from the buffer, into the provided buffer. |
| 360 | // Returns the number of bytes read, or 0 in case of an error. |
| 361 | uint32_t DataBuffer::read(uint32_t len, uint8_t* bytes) { |
| 362 | #ifdef DEBUG |
| 363 | std::cout << "DataBuffer::read: len " << len << ". EOF: " << eof << std::endl; |
| 364 | #endif |
| 365 | |
| 366 | #ifdef PROFILING_DB |
| 367 | std::chrono::high_resolution_clock::time_point begin = std::chrono::high_resolution_clock::now(); |
| 368 | #endif |
| 369 | |
| 370 | // Request more data if the buffer does not have enough unread data left, and EOF condition |
| 371 | // has not been reached. |
| 372 | while (!eof && len > unread) { |
| 373 | // More data should be available on the client, try to request it. |
| 374 | #ifdef DEBUG |
| 375 | std::cout << "Requesting more data... buffering: " << buffering |
| 376 | << ", bufferAhead: " << bufferAhead << std::endl; |
| 377 | #endif |
| 378 | |
| 379 | #ifdef PROFILING_DB |
| 380 | db_debugfile << "Requesting more data... Unread: " << unread << ".\n"; |
| 381 | #endif |
| 382 | if (buffering) { |
| 383 | // If we're buffering, a write should be coming soon, so give it a few ms. |
| 384 | // If we time-out, assume something went wrong and override. |
| 385 | std::unique_lock<std::mutex> lk(dataReadMutex); |
| 386 | using namespace std::chrono_literals; |
| 387 | uint32_t timeout = 1000; |
| 388 | bool success = true; |
| 389 | while (1) { |
| 390 | dataReadCV.wait_for(lk, 100us); |
| 391 | if (!dataRequestPending) { break; } |
| 392 | if (--timeout == 0) { |
| 393 | #ifdef DEBUG |
| 394 | std::cerr << "Buffering Read: RequestData timeout after 100 ms." << std::endl; |
| 395 | #endif |
| 396 | dataRequestPending = false; |
| 397 | success = requestData(); |
| 398 | break; |
| 399 | } |
| 400 | |
| 401 | if (!success) { |
| 402 | #ifdef DEBUG |
| 403 | std::cerr << "Buffering Read: data request failed. Aborting read." << std::endl; |
| 404 | #endif |
| 405 | return 0; |
| 406 | } |
| 407 | } |
| 408 | |
| 409 | // Sanity check to see whether we're good now. |
| 410 | if (!eof && len > unread) { |
| 411 | success = requestData(); |
| 412 | if (!success) { |
| 413 | #ifdef DEBUG |
| 414 | std::cerr << "Buffering Read: buffer check failed. Aborting read." << std::endl; |
| 415 | #endif |
| 416 | return 0; |
| 417 | } |
| 418 | } |