Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Third Party Mirror: A question about the thread safety of the custom NetworkReader/Writer

Discussion in 'Multiplayer' started by ktxiaok, Jun 23, 2022.

  1. ktxiaok

    ktxiaok

    Joined:
    May 13, 2022
    Posts:
    9
    I want to send bytes in mirror networking framework. To avoid gc allocation, I use my global memory allocator instead of byte array in my custom NetworkReader/Writer. I want to know if the thread where the read/write method is executed is the same as the unity main thread. Is there any thread safety problem?
     
  2. Punfish

    Punfish

    Joined:
    Dec 7, 2014
    Posts:
    389
    It's on the Unity thread.
     
  3. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Use ArraySegment instead of byte[].
    Mirror does not allocate anything in hot path.
    Neither does your game need to :)
     
  4. ktxiaok

    ktxiaok

    Joined:
    May 13, 2022
    Posts:
    9
    Thank you very much for answering my question!

    Actually when data is being received, a segment of memory is needed to store the data. I use my global memory allocator(static class) in my NetworkReader. The read method return the pointer to the memory of received data. So I'm worried about the thread safety problem because it uses a global static class. This is a solution I've come up with so far. There may be a better solution.

    The write method is not so troublesome because the memory of the data to be sent already exists. But there is a small problem. The owner of the memory don't know when the data has been sent. My solution is that I send a notification to the owner at the end of the write method. So again, this relate to the thread safety.

    I saw someone say that these are executed on the unity main thread and I can also know it by printing the current thread in the read/write method. But it's not certain that the mirror will use multithreaded network reader and writer in the future.
     
  5. ktxiaok

    ktxiaok

    Joined:
    May 13, 2022
    Posts:
    9
    Thank you very much!
    But I wonder if the mirror will use multithreaded network reader and writer in the future.
     
  6. JamesFrowenDev

    JamesFrowenDev

    Joined:
    Oct 10, 2015
    Posts:
    20
    A high level view of how mirror works:
    - Packet is received by Transport
    - Transport gets byte[] from pool (only allocates new array if pool is empty)
    - Transport works out packet headers and then create ArraySegment that contain messages
    - ArraySegment with Message is then passed to Mirror's high level
    - NetworkReader then uses ArraySegment, and deserializes the message (if the message/fields are all structs then nothing is allocated)
    - Once the message has been handled, the Transport will put the byte[] back into the pool so it can be reused (at this point the ArraySegment is invalid and should not be used)

    Mirror's serialize/desterilize itself should be mostly thread safe, Writing types like
    int, float, vector3
    (primitive types and custom structs made of them) should all be safe. Writing types that are linked to main thread like GameObject, or NetworkIdentity, might cause problems if they call into one of unity's functions.

    If you are using the ArraySegment from mirror's transport you will need to copy the data out of it, because the transport might pool the internal array, causing old data in the arraySegment to be overwritten.

    One extra thing to note: Most Transport are not thread safe, so doing serialize/desterilize on side threads wont give you much benefit, it just adds complexity of dealing with multiple threads.
     
  7. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Not sure what you are trying to do with threaded serialization here.
    Unity is not thread safe, and all your world lives on the main thread.
    So by definition, you need to serialize in that main thread as well.

    There are other parts which you can potentially move onto threads.
    We are experimenting with this atm :)
     
  8. ktxiaok

    ktxiaok

    Joined:
    May 13, 2022
    Posts:
    9
    Many thanks! Now I understand.