net.IpConnectionUseSendTasks
net.IpConnectionUseSendTasks
#Overview
name: net.IpConnectionUseSendTasks
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
If true, the IpConnection will call the socket\'s SendTo function in a task graph task so that it can run off the game thread.
It is referenced in 8
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of net.IpConnectionUseSendTasks is to control whether the IpConnection will call the socket’s SendTo function in a task graph task, allowing it to run off the game thread. This setting is primarily used for networking optimization in Unreal Engine.
This setting variable is primarily used in the OnlineSubsystemUtils module, specifically within the IpConnection class. It affects how network data is sent over IP connections.
The value of this variable is set through a console variable (CVarNetIpConnectionUseSendTasks) defined in IpConnection.cpp. It defaults to 0 (false) but can be changed at runtime.
The associated variable CVarNetIpConnectionUseSendTasks directly interacts with net.IpConnectionUseSendTasks. They share the same value and are used interchangeably in the code.
Developers must be aware that enabling this setting (setting it to non-zero) will change the behavior of how network data is sent. It will use task graph tasks for sending data, which can improve performance by offloading work from the game thread but may also introduce additional complexity in debugging and synchronization.
Best practices when using this variable include:
- Test thoroughly with both enabled and disabled states to ensure your game performs well in both scenarios.
- Monitor performance metrics to determine if enabling this feature provides a significant benefit for your specific use case.
- Be cautious when enabling this in production, as it changes the threading model for network operations.
Regarding the associated variable CVarNetIpConnectionUseSendTasks:
- Its purpose is to provide a runtime-configurable way to enable or disable the use of send tasks for IP connections.
- It is used throughout the IpConnection class to check whether send tasks should be used.
- The value is typically accessed using GetValueOnGameThread() or GetValueOnAnyThread() methods.
- When enabled, it affects various parts of the networking code, including how data is sent, how cleanup is performed, and how the connection waits for send tasks to complete.
- Developers should be aware that changing this value at runtime will immediately affect the behavior of all IP connections in the game.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/IpConnection.cpp:36
Scope: file
Source code excerpt:
TAutoConsoleVariable<int32> CVarNetIpConnectionUseSendTasks(
TEXT("net.IpConnectionUseSendTasks"),
0,
TEXT("If true, the IpConnection will call the socket's SendTo function in a task graph task so that it can run off the game thread."));
TAutoConsoleVariable<int32> CVarNetIpConnectionDisableResolution(
TEXT("net.IpConnectionDisableResolution"),
0,
#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Classes/IpConnection.h:87
Scope (from outer to inner):
file
function class ONLINESUBSYSTEMUTILS_API UIpConnection : public UNetConnection { GENERATED_UCLASS_BODY
Source code excerpt:
private:
/**
* Struct to hold the result of a socket SendTo call. If net.IpConnectionUseSendTasks is true,
* these are communicated back to the game thread via SocketSendResults.
*/
struct FSocketSendResult
{
int32 BytesSent = 0;
ESocketErrors Error = SE_NO_ERROR;
};
/** Critical section to protect SocketSendResults */
FCriticalSection SocketSendResultsCriticalSection;
/** Socket SendTo results from send tasks if net.IpConnectionUseSendTasks is true */
TArray<FSocketSendResult> SocketSendResults;
/**
* If net.IpConnectionUseSendTasks is true, reference to the last send task used as a prerequisite
* for the next send task. Also, CleanUp() blocks until this task is complete.
*/
FGraphEventRef LastSendTask;
/** The socket used for communication (typically shared between NetConnection's, Net Address Resolution, and the NetDriver) */
TSharedPtr<FSocket> SocketPrivate;
/** List of previously active sockets for this connection, whose cleanup is deferred for multithreaded safety and to prevent remote ICMP errors */
TArray<TSharedPtr<FSocket>> DeferredCleanupSockets;
#Associated Variable and Callsites
This variable is associated with another variable named CVarNetIpConnectionUseSendTasks
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Classes/IpConnection.h:63
Scope (from outer to inner):
file
function class ONLINESUBSYSTEMUTILS_API UIpConnection : public UNetConnection { GENERATED_UCLASS_BODY
Source code excerpt:
/**
* If CVarNetIpConnectionUseSendTasks is true, blocks until there are no outstanding send tasks.
* Since these tasks need to access the socket, this is called before the net driver closes the socket.
*/
void WaitForSendTasks();
/**
* Gets the cached socket for this connection.
*
* @return The cached socket for this connection
*/
#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/IpConnection.cpp:35
Scope: file
Source code excerpt:
DECLARE_CYCLE_STAT(TEXT("IpConnection WaitForSendTasks"), STAT_IpConnection_WaitForSendTasks, STATGROUP_Net);
TAutoConsoleVariable<int32> CVarNetIpConnectionUseSendTasks(
TEXT("net.IpConnectionUseSendTasks"),
0,
TEXT("If true, the IpConnection will call the socket's SendTo function in a task graph task so that it can run off the game thread."));
TAutoConsoleVariable<int32> CVarNetIpConnectionDisableResolution(
TEXT("net.IpConnectionDisableResolution"),
#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/IpConnection.cpp:182
Scope (from outer to inner):
file
function void UIpConnection::Tick
Source code excerpt:
using namespace UE::Net::Private;
if (CVarNetIpConnectionUseSendTasks.GetValueOnGameThread() != 0)
{
ISocketSubsystem* const SocketSubsystem = Driver->GetSocketSubsystem();
TArray<FSocketSendResult> ResultsCopy;
{
FScopeLock ScopeLock(&SocketSendResultsCriticalSection);
#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/IpConnection.cpp:363
Scope (from outer to inner):
file
function void UIpConnection::SafeDeferredSocketCleanup
Source code excerpt:
DeferredCleanupTimeCheck = LastReceiveRealtime;
if (CVarNetIpConnectionUseSendTasks.GetValueOnGameThread() != 0 && LastSendTask.IsValid())
{
DECLARE_CYCLE_STAT(TEXT("IpConnection SocketCleanup task"), STAT_IpConnection_SocketCleanupTask, STATGROUP_TaskGraphTasks);
FGraphEventArray Prerequisites;
Prerequisites.Add(LastSendTask);
#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/IpConnection.cpp:402
Scope (from outer to inner):
file
function void UIpConnection::WaitForSendTasks
Source code excerpt:
void UIpConnection::WaitForSendTasks()
{
if (CVarNetIpConnectionUseSendTasks.GetValueOnGameThread() != 0 && LastSendTask.IsValid())
{
check(IsInGameThread());
SCOPE_CYCLE_COUNTER(STAT_IpConnection_WaitForSendTasks);
FTaskGraphInterface::Get().WaitUntilTaskCompletes(LastSendTask, ENamedThreads::GameThread);
#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/IpConnection.cpp:501
Scope (from outer to inner):
file
function void UIpConnection::LowLevelSend
Source code excerpt:
FSocket* CurSocket = GetSocket();
if (CVarNetIpConnectionUseSendTasks.GetValueOnAnyThread() != 0)
{
DECLARE_CYCLE_STAT(TEXT("IpConnection SendTo task"), STAT_IpConnection_SendToTask, STATGROUP_TaskGraphTasks);
FGraphEventArray Prerequisites;
if (LastSendTask.IsValid())
{