home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / spmio10.zip / gcc2 / pmio / eventq.cc < prev    next >
C/C++ Source or Header  |  1994-06-10  |  3KB  |  108 lines

  1.  
  2. #define INCL_DOSSEMAPHORES
  3. #define INCL_DOSERRORS
  4. #include <os2.h>
  5. #include "eventq.h"
  6.  
  7. class ActualPMIOEventQ: public PMIOEventQ
  8. {
  9.   const unsigned q_size;
  10.   unsigned q_head, q_tail, q_len;
  11.   HEV q_event_semaphore;
  12.   HMTX q_mutex_semaphore;
  13.   PMIOEvent * const q;
  14.   virtual void nonblocking_insert (const PMIOEvent *);
  15.   virtual void blocking_remove (PMIOEvent *);
  16.   virtual int event_availible ();
  17. public:
  18.   ActualPMIOEventQ (unsigned size);
  19. };
  20.  
  21. void ActualPMIOEventQ::nonblocking_insert (const PMIOEvent *e)
  22. {
  23.   int rc;
  24.   // Obtain mutex access
  25.   do
  26.     rc = DosRequestMutexSem (q_mutex_semaphore,
  27.                  (unsigned) SEM_INDEFINITE_WAIT);
  28.   while (rc == ERROR_INTERRUPT);
  29.   // Insert
  30.   if (q_len < q_size)
  31.     {
  32.       q[q_head] = *e;
  33.       q_len++;
  34.       if (++q_head >= q_size)
  35.     q_head = 0;
  36.     }
  37.   // Unblock anyone waiting for this to happen
  38.   DosPostEventSem (q_event_semaphore);
  39.   // Release mutex access
  40.   DosReleaseMutexSem (q_mutex_semaphore);
  41. }
  42.  
  43. void ActualPMIOEventQ::blocking_remove (PMIOEvent *e)
  44. {
  45.   // Clear the event semaphore
  46.   unsigned long foo;
  47.   DosResetEventSem (q_event_semaphore, &foo);
  48.  
  49.   int rc;
  50.   for (;;)
  51.     {
  52.       // Get mutex
  53.       do
  54.     rc = DosRequestMutexSem (q_mutex_semaphore,
  55.                  (unsigned) SEM_INDEFINITE_WAIT);
  56.       while (rc == ERROR_INTERRUPT);
  57.       // Get the length of the queue
  58.       unsigned len = q_len;
  59.       // If there is something in the queue, dequeue it
  60.       if (len > 0)
  61.     {
  62.       *e = q[q_tail];
  63.       q_len--;
  64.       if (++q_tail >= q_size)
  65.         q_tail = 0;
  66.     }
  67.       // Release the mutex
  68.       DosReleaseMutexSem (q_mutex_semaphore);
  69.       // If we got something, we're done
  70.       if (len > 0)
  71.     break;
  72.       // Otherwise, wait for an event to come in
  73.       DosWaitEventSem (q_event_semaphore, (unsigned) SEM_INDEFINITE_WAIT);
  74.     }
  75. }
  76.  
  77. int ActualPMIOEventQ::event_availible ()
  78. {
  79.   // Get mutex
  80.   int rc;
  81.   do
  82.     rc = DosRequestMutexSem (q_mutex_semaphore,
  83.                  (unsigned) SEM_INDEFINITE_WAIT);
  84.   while (rc == ERROR_INTERRUPT);
  85.   // Get the length of the queue
  86.   unsigned len = q_len;
  87.   // Release the mutex
  88.   DosReleaseMutexSem (q_mutex_semaphore);
  89.   // return the result
  90.   return len > 0;
  91. }
  92.   
  93. ActualPMIOEventQ::ActualPMIOEventQ (unsigned size)
  94. : q_size (size),
  95.   q_head (0),
  96.   q_tail (0),
  97.   q_len (0),
  98.   q (new PMIOEvent[size])
  99. {
  100.   DosCreateEventSem (0, &q_event_semaphore, 0, 0);
  101.   DosCreateMutexSem (0, &q_mutex_semaphore, 0, 0);
  102. }
  103.  
  104. PMIOEventQ *pmio_make_eventq (unsigned size)
  105. {
  106.   return new ActualPMIOEventQ (size);
  107. }
  108.