Download

Delegate thread safety

How thread safe are delegates?

I’m running some TCP connection code in different thread.
When a certain message is received i would like to call a delegate, but how thread safe are these?

The delegate handlers will spawn actors, remove actors, change actor properties … depending on the received message.

EDIT:
Or would it be better to have a lockable queue on the game instance which process the messages in the tick method?

I don’t know about delegates themselves, but yeah if you’re doing anything involving actors/world, you flat out need to be doing it on the game thread only. You won’t be able to directly invoke a delegate doing anything like that from an external thread.

Pretty sure your edit is the way to go. TQueue is thread-safe and lock free.

Thats great, just checked the information on the TQueue, exactly what i need :slight_smile:
Din’t know there were thread safe / lock-less collection templates available.

Or you could just push it onto the TaskGraph and mention in the Task that it’s only supposed to run on the game thread.

See [FONT=Courier New]TaskGraphInterfaces.h and the comment on line 498-ish:


/** 
 The user defined task type can take arguments to a constructor. These arguments (unfortunately) must not be references.
 The API required of TTask:

class FGenericTask
{
	TSomeType	SomeArgument;
public:
	FGenericTask(TSomeType InSomeArgument) // CAUTION!: Must not use references in the constructor args; use pointers instead if you need by reference
		: SomeArgument(InSomeArgument)
	{
		// Usually the constructor doesn't do anything except save the arguments for use in DoWork or GetDesiredThread.
	}
	~FGenericTask()
	{
		// you will be destroyed immediately after you execute. Might as well do cleanup in DoWork, but you could also use a destructor.
	}
	FORCEINLINE TStatId GetStatId() const
	{
		RETURN_QUICK_DECLARE_CYCLE_STAT(FGenericTask, STATGROUP_TaskGraphTasks);
	}

	[static] ENamedThreads::Type GetDesiredThread()
	{
		return ENamedThreads::[named thread or AnyThread];
	}
	void DoTask(ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent)
	{
		// The arguments are useful for setting up other tasks. 
		// Do work here, probably using SomeArgument.
		MyCompletionGraphEvent->DontCompleteUntil(TGraphTask<FSomeChildTask>::CreateTask(NULL,CurrentThread).ConstructAndDispatchWhenReady());
	}
};
**/

As mentioned bad things happen if you create actors on any other thread