using System; using System.Threading; namespace org.budnhead { /** * ConsumerProducerLock * * Lock a Resource for one producer, mutliple consumers (read-only) * * Producer Lock: Producer will receive and hold lock if no other producer is active * Producer Exclusive Lock: Producer will receive and hold lock, while no consumers are active * Consumer Lock: Consumers will get lock while no Producer Exclusive Lock is held * **/ public class ConsumerProducerLock { Object producer; Object producerExclusiveLock; Object consumerLock; Int32 consumers; bool producerIsExclusive; public ConsumerProducerLock(){ producer = new object(); producerExclusiveLock = new object(); consumerLock = new object(); consumers = 0; } public void ConsumerEnter(){ Monitor.Enter(producerExclusiveLock); Monitor.Enter(consumerLock); consumers ++; Monitor.Exit(consumerLock); Monitor.Exit(producerExclusiveLock); } public void ConsumerExit(){ Monitor.Enter(producerExclusiveLock); Monitor.Enter(consumerLock); consumers --; if (consumers == 0){ Monitor.Pulse(producerExclusiveLock); } Monitor.Exit(consumerLock); Monitor.Exit(producerExclusiveLock); } public void ProducerEnter(){ Monitor.Enter(producer); } public void ProducerExit(){ Monitor.Exit(producer); if (Monitor.IsEntered(producerExclusiveLock)){ Monitor.Exit(producerExclusiveLock); } } public void producerExclusive(){ Monitor.Enter(producerExclusiveLock); if (consumers > 0){ Monitor.Wait(producerExclusiveLock); } } } }