PacketLock Class |
Namespace: Demo3D.IO
public sealed class PacketLock : IDisposable
The PacketLock type exposes the following members.
| Name | Description | |
|---|---|---|
| PacketLock | Initializes a new instance of the PacketLock class |
| Name | Description | |
|---|---|---|
| Dispose |
Disposes the lock.
| |
| LockAsync |
Locks the lock and return a key that can be used to unlock it.
| |
| Unlock |
Unlocks the lock using the key that locked it.
|
Write locking is quite simple. We create a lock object (PacketLock) and pass it into Packet.Create(). StreamPacketWriter then takes the lock just for the duration of flushing the packet to the stream.
Read locking for message-stream protocols(such as COTP, or UDP) is also simple. If you've read a packet from a message-stream protocol, then the PacketReader you get returned to you is a FixedPacketReader and contains all the data for that message. You don't need to lock anything to read data from the packet.
But read locking for a byte-stream protocol (TCP) is a bit more complicated. If there are two threads both attempting to exchange protocol messages with a single server (over one connection), then you need to lock access to the byte-stream while you read the message.Unfortunately, we don't know the message boundaries, and possibly neither would our parent protocol. It may be several protocols up before we know the true boundaries of a message.
The solution is to grab the readLock when we first start reading a message.We pass the key to the PacketReader and it unlocks the lock when the packet is closed.
This requires support from PacketReader so that it only closes the top-level packet and unlocks the byte-stream when the last child packet is closed.
We also need this lock to be an Async lock, and it needs to be a semaphore so the lock isn't associated with any particular thread, but rather with a particular caller.