using System; using System.Threading; using Microsoft.SPOT; namespace LOGGER { public class SynchronizedLogEntryQueue : LogEntryQueue { private object _sync; private int _consumersWaiting; private int _producersWaiting; private AutoResetEvent _available; public SynchronizedLogEntryQueue(int capacity) : base(capacity) { _available = new AutoResetEvent(false); _sync = new object(); _consumersWaiting = 0; _producersWaiting = 0; } public bool Queued() { bool emptyQ; lock (_sync) { emptyQ = Empty(); } return emptyQ; } public void Add(LogEntry e) { Monitor.Enter(_sync); try { while (Full()) { _producersWaiting++; Monitor.Exit(_sync); _available.WaitOne(); Monitor.Enter(_sync); _producersWaiting--; } Insert(e); if (_consumersWaiting > 0) _available.Set(); } finally { Monitor.Exit(_sync); } } public LogEntry Remove(ref LogEntry e) { LogEntry item; Monitor.Enter(_sync); try { while (Empty()) { _consumersWaiting++; Monitor.Exit(_sync); _available.WaitOne(); Monitor.Enter(_sync); _consumersWaiting--; } item = Delete(); e = (LogEntry)item.Clone(); if (_producersWaiting > 0) _available.Set(); } finally { Monitor.Exit(_sync); } return item; } } }