SleepyQueue

I discovered in my Curse of the Azure Bonds port that I was handling system interrupts related to keyboard input incorrectly. What I needed was a blocking getKey function when keys were buffered. So I wrote some code to solve this using lock and a semaphore. Today I rewrote it into a generic class. Here it is:

public class SleepyQueue  
{  
  Queue queue;  
  Semaphore semaphore;  

  public SleepyQueue()  
  {  
    queue = new Queue();  
    semaphore = new Semaphore(0, 1);  
  }  

  public void Enqueue(T t)  
  {  
    lock (queue)  
    {  
      queue.Enqueue(t);  
      if (queue.Count == 1)  
      {  
        semaphore.Release();  
      }  
    }  
  }  

  public T Dequeue()  
  {  
    T item;  
    semaphore.WaitOne();  
    lock (queue)  
    {  
      item = queue.Dequeue();  
      if (queue.Count > 0)  
      {  
        semaphore.Release();  
      }  
    }  

    return item;  
  }  
}  

This can be used like so

static void Main(string[] args)  
{  
  SleepyQueue<int> q = new SleepyQueue<int>();  

  q.Enqueue(1);  
  q.Enqueue(2);  
  q.Enqueue(3);  

  Timer t = new Timer(CallBack, q, 3000, 3000);  

  while (true)  
  {  
    Console.WriteLine(q.Dequeue());  
  }  
}  

static void CallBack(object state)  
{  
  SleepyQueue<int> q = (SleepyQueue<int>)state;  
  q.Enqueue(System.DateTime.UtcNow.Second);  
}  

Then this morning our new developer was asking how to use IEnumerable<> to loops across a queue of objects, and it was the same lock/semaphore type problem.

I started modifying my generic class so I could post the code, but it got nasty quite quickly, so I’ll just pass for now, and work on getting our code correct…