How to lock access to shared resource in 2 threads.

I want to simplify the architecture of what I’m doing.
I have a textured material. Let’s call it MainTex
That is to be updated on main thread like normal.
Main Thread
MainTex = CurrentStreamingTexture;
Other Thread (receives live stream of live video)
CurrentStreamingTexture = current video frame from live video stream.

What is best method to block access to CurrentStreamingTexture between the two threads that share it, until that thread is done?

The “Other Thread” may go through 10 frames before the main thread gets around to asking for the CurrentStreamingTexture
So when it wants to update MainTex it has to wait for the CurrentStreamingTexture to finish being updated in “Other Thread”.
And vice versa, the “Other Thread” has to wait for MainThread to finish updating MainTex with CurrentStreamingTexture …before OtherThread can then update CurrentStreamingTexture itself with the new video frame.

Unreal already provides a way to lock access to textures: MainTex->GetPlatformData()->Mips[0]->BulkData->Lock(LOCK_READ_WRITE) or MainTex->GetPlatformData()->Mips[0]->BulkData->LockReadOnly(). Then use MainTex->GetPlatformData()->Mips[0].BulkData.Unlock() to unlock the texture.

You can then use MainTex->GetPlatformData()->Mips[0]->BulkData->IsUnlocked() to check if it’s been locked.

I don’t 100% understand your case but it sounds like you don’t really need the two threads writing to the same texture anyways.

1 Like

While the other thread may be 10 frames ahead (maybe not, I have not gotten to that part yet)…it will always be updating and using the CurrentStreamingTexture as a buffer to be read on main thread.
I may force it so that the main thread is always in sync and gets and uses every video frame…the method I describe means that the main thread will skip x amount of video frames. it would be a small amount. while the other thread always gets all the video frames.
So if there are 100 video frames received. The main thread may only display every 5th one or something like that. I may force it so that if the other thread gets 100 video frames the main thread will also display the full 100 video frames. I hope that explains it a little clearer.

Thanks for information, I will try it out.

What should I do with IsUnlocked()?
Do I keep calling it till it returns true? Or do I sleep?
Or does it wait automatically till it’s true?

You will

If you’re on the main thread, you have no choice other than to call it every frame until it is true. If on the ‘other thread’, you don’t really need to sleep as you should already have some form of tiny sleep in your thread’s tick.

Now that I understand your use case more. You have two methods.

  1. Use the locking procedure I mentioned before: The other thread only starts writing data when the texture is unlocked, and will lock it for reading and writing. The main thread will only start reading the data when the texture is unlocked, and will lock it for reading.

  2. Instead of letting the main thread read the texture, use a second texture object and clone the original texture data into this texture, then read the second texture object.

The first method is preferred as the second method does result in some extra computations but it does completely remove the synchronisation issues.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.