Example #1
0
void
RethinkPlayers ( struct AHIDevUnit *iounit,
                 struct AHIBase *AHIBase )
{
  struct MinList templist;
  struct AHIRequest *ioreq;

  NewList((struct List *) &templist);

  ObtainSemaphore(&iounit->ListLock);

  RemPlayers((struct List *) &iounit->PlayingList, iounit, AHIBase);
  RemPlayers((struct List *) &iounit->SilentList, iounit, AHIBase);

  // Move all silent requests to our temporary list

  while((ioreq = (struct AHIRequest *) RemHead((struct List *) &iounit->SilentList)))
  {
    AddTail((struct List *) &templist, (struct Node *) ioreq);
  }

  // And add them back...
  while((ioreq = (struct AHIRequest *) RemHead((struct List *) &templist)))
  {
    AddWriter(ioreq, iounit, AHIBase);
  }

  ReleaseSemaphore(&iounit->ListLock);
}
Example #2
0
bool CRWLockImpl::TryWriteLockImpl()
{
	AddWriter();
	HANDLE h[2];
	h[0] = m_mutex;
	h[1] = m_writeEvent;
	switch (WaitForMultipleObjects(2, h, TRUE, 1))
	{
	case WAIT_OBJECT_0:
	case WAIT_OBJECT_0 + 1:
		--m_writersWaiting;
		++m_readers;
		++m_writers;
		ResetEvent(m_readEvent);
		ResetEvent(m_writeEvent);
		ReleaseMutex(m_mutex);
		assert(m_writers == 1);
		return true;
	case WAIT_TIMEOUT:
		RemoveWriter();
	default:
		RemoveWriter();
		cout<<"cannot lock reader/writer lock"<<endl;
	}
	return false;
}
Example #3
0
void CRWLockImpl::WriteLockImpl()
{
	AddWriter();
	HANDLE h[2];
	h[0] = m_mutex;
	h[1] = m_writeEvent;
	switch (WaitForMultipleObjects(2, h, TRUE, INFINITE))
	{
	case WAIT_OBJECT_0:
	case WAIT_OBJECT_0 + 1:
		--m_writersWaiting;
		++m_readers;
		++m_writers;
		ResetEvent(m_readEvent);
		ResetEvent(m_writeEvent);
		ReleaseMutex(m_mutex);
		assert(m_writers == 1);
		break;
	default:
		RemoveWriter();
		cout<<"cannot lock reader/writer lock"<<endl;
	}
}
Example #4
0
static void
NewWriter ( struct AHIRequest *ioreq,
            struct AHIDevUnit *iounit,
            struct AHIBase *AHIBase )
{
  int channel, sound;
  BOOL delay = FALSE;
  struct AHISampleInfo si;
  struct Library *AHIsubBase;

  AHIsubBase = ((struct AHIPrivAudioCtrl *) iounit->AudioCtrl)->ahiac_SubLib;

  si.ahisi_Type    = ioreq->ahir_Type;
  si.ahisi_Address = ioreq->ahir_Std.io_Data;
  si.ahisi_Length  = ioreq->ahir_Std.io_Length;

  // Load the sound
  
  for(sound = 0; sound < MAXSOUNDS; sound++)
  {
    if(iounit->Sounds[sound] == SOUND_FREE)
    {
      iounit->Sounds[sound] = SOUND_IN_USE;
      break;
    }
  }

  if((sound < MAXSOUNDS) &&
     (AHI_LoadSound(sound, AHIST_DYNAMICSAMPLE, &si, iounit->AudioCtrl)
      == AHIE_OK)) {

    GetExtras(ioreq)->Sound = sound;

    ObtainSemaphore(&iounit->ListLock);
  
    if(ioreq->ahir_Link)
    {
      // See if the linked request is playing, silent or waiting...
  
      if(FindNode((struct List *) &iounit->PlayingList,
          (struct Node *) ioreq->ahir_Link))
      {
        delay = TRUE;
      }
      else if(FindNode((struct List *) &iounit->SilentList,
          (struct Node *) ioreq->ahir_Link))
      {
        delay = TRUE;
      }
      else if(FindNode((struct List *) &iounit->WaitingList,
          (struct Node *) ioreq->ahir_Link))
      {
        delay = TRUE;
      }
    }

  // NOTE: ahir_Link changes direction here. When the user set's it, she makes a new
  // request point to an old. We let the old point to the next (that's more natural,
  // anyway...) It the user tries to link more than one request to another, we fail.
  
    if(delay)
    {
      if( ! ioreq->ahir_Link->ahir_Link)
      {
        struct AHIRequest *otherioreq = ioreq->ahir_Link;
      
        channel = GetExtras(ioreq->ahir_Link)->Channel;
        GetExtras(ioreq)->Channel = NOCHANNEL;
  
        otherioreq->ahir_Link = ioreq;
        ioreq->ahir_Link = NULL;
        Enqueue((struct List *) &iounit->WaitingList,(struct Node *) ioreq);
  
        if(channel != NOCHANNEL)
        {
          // Attach the request to the currently playing one
  
          AHIsub_Disable((struct AHIAudioCtrlDrv *) iounit->AudioCtrl);

          // Make SURE the current sound isn't already finished!
          
          if(otherioreq->ahir_Std.io_Command == AHICMD_WRITTEN)
          {
            AHIsub_Enable((struct AHIAudioCtrlDrv *) iounit->AudioCtrl);

            // OOPS! It's finished! Undo...
            Remove((struct Node *) ioreq);
            
            // Start sound as if it wasn't delayed (see below);
            AddWriter(ioreq, iounit, AHIBase);
          }
          else
          {
            iounit->Voices[channel].QueuedRequest = ioreq;
            iounit->Voices[channel].NextOffset  = PLAY;
            iounit->Voices[channel].NextRequest = NULL;
            AHI_Play(iounit->AudioCtrl,
                AHIP_BeginChannel,  channel,
                AHIP_LoopFreq,      ioreq->ahir_Frequency,
                AHIP_LoopVol,       ioreq->ahir_Volume,
                AHIP_LoopPan,       ioreq->ahir_Position,
                AHIP_LoopSound,     GetExtras(ioreq)->Sound,
                AHIP_LoopOffset,    ioreq->ahir_Std.io_Actual,
                AHIP_LoopLength,    ioreq->ahir_Std.io_Length - ioreq->ahir_Std.io_Actual,
                AHIP_EndChannel,    NULL,
                TAG_DONE);
            AHIsub_Enable((struct AHIAudioCtrlDrv *) iounit->AudioCtrl);
          }

        }
      }
      else // She tried to add more than one request to another one
      { 
        ioreq->ahir_Std.io_Error = AHIE_UNKNOWN;
        TermIO(ioreq, AHIBase);
      }
    }
    else // Sound is not delayed
    {
      ioreq->ahir_Link=NULL;
      AddWriter(ioreq, iounit, AHIBase);
    }

    ReleaseSemaphore(&iounit->ListLock);
  }
  else // No free sound found, or sound failed to load
  {
    ioreq->ahir_Std.io_Error = AHIE_UNKNOWN;
    TermIO(ioreq, AHIBase);
  }
}