| 1468 | } |
| 1469 | |
| 1470 | void Test_send_buffer_full() |
| 1471 | { |
| 1472 | TEST_Printf( "***************************************************\n" ); |
| 1473 | TEST_Printf( "Test: SendMessages batch stop and retry on buffer full\n" ); |
| 1474 | TEST_Printf( "***************************************************\n" ); |
| 1475 | |
| 1476 | // Network loopback so we get real rate limiting |
| 1477 | HSteamNetConnection hSender, hRecver; |
| 1478 | assert( SteamNetworkingSockets()->CreateSocketPair( &hSender, &hRecver, true, nullptr, nullptr ) ); |
| 1479 | SteamNetworkingSockets()->SetConnectionName( hSender, "sender" ); |
| 1480 | SteamNetworkingSockets()->SetConnectionName( hRecver, "recver" ); |
| 1481 | |
| 1482 | // Low send rate so the buffer stays full long enough to observe |
| 1483 | const int k_nSendRate = 64 * 1024; |
| 1484 | SteamNetworkingUtils()->SetConnectionConfigValueInt32( hSender, k_ESteamNetworkingConfig_SendRateMin, k_nSendRate ); |
| 1485 | SteamNetworkingUtils()->SetConnectionConfigValueInt32( hSender, k_ESteamNetworkingConfig_SendRateMax, k_nSendRate ); |
| 1486 | |
| 1487 | // Buffer fits one 100K message but not two, so msg[1] overflows and msg[2] is never attempted |
| 1488 | const int k_cbMsg = 100 * 1024; |
| 1489 | const int k_nSendBuffer = 160 * 1024; |
| 1490 | SteamNetworkingUtils()->SetConnectionConfigValueInt32( hSender, k_ESteamNetworkingConfig_SendBufferSize, k_nSendBuffer ); |
| 1491 | |
| 1492 | // Prepare three reliable messages |
| 1493 | SteamNetworkingMessage_t *pMessages[3]; |
| 1494 | for ( int i = 0; i < 3; ++i ) |
| 1495 | { |
| 1496 | pMessages[i] = SteamNetworkingUtils()->AllocateMessage( k_cbMsg ); |
| 1497 | pMessages[i]->m_conn = hSender; |
| 1498 | pMessages[i]->m_nFlags = k_nSteamNetworkingSend_Reliable; |
| 1499 | } |
| 1500 | |
| 1501 | // Send all three at once. Pass bDeleteFailedMessages=false so the library |
| 1502 | // leaves failed/not-attempted message pointers in place for retry. |
| 1503 | int64 results[3] = {}; |
| 1504 | SteamNetworkingSockets()->SendMessages( 3, pMessages, results, /*bDeleteFailedMessages=*/false ); |
| 1505 | |
| 1506 | // First message fits in the 160K buffer: should succeed |
| 1507 | assert( results[0] > 0 ); |
| 1508 | assert( pMessages[0] == nullptr ); // library took ownership |
| 1509 | |
| 1510 | // Second message overflows the buffer: should fail |
| 1511 | assert( results[1] == -k_EResultLimitExceeded ); |
| 1512 | assert( pMessages[1] != nullptr ); // we still own it; can retry |
| 1513 | |
| 1514 | // Third message was never attempted because the second failed |
| 1515 | assert( results[2] == 0 ); |
| 1516 | assert( pMessages[2] != nullptr ); // we still own it; can retry |
| 1517 | |
| 1518 | TEST_Printf( "Initial send: msg[0]=#%lld succeeded, msg[1]=LimitExceeded, msg[2]=not attempted.\n", results[0] ); |
| 1519 | |
| 1520 | // Retry the two remaining messages one at a time. The buffer only holds one |
| 1521 | // 100K message, so we must wait for space before each retry. |
| 1522 | SteamNetworkingMessage_t *pRetry[2] = { pMessages[1], pMessages[2] }; |
| 1523 | for ( int i = 0; i < 2; ++i ) |
| 1524 | { |
| 1525 | TEST_Printf( "Waiting for buffer space (retry %d)...\n", i ); |
| 1526 | SteamNetworkingMicroseconds usecDeadline = SteamNetworkingUtils()->GetLocalTimestamp() + 10 * 1000000LL; |
| 1527 | for (;;) |
nothing calls this directly
no test coverage detected