Example #1
0
    // throws InvalidOperationException
    public void UpWrite()
    {
        lock (lockObj)
        {
            //se n tiver sido invocado por uma thread que invocou o DownWrite
            //lança excepção
            if (writerInside != Thread.CurrentThread.ManagedThreadId)
            {
                throw new InvalidOperationException();
            }

            //Nenhum escritor a escrever
            isWriting = false;

            //Se houver leitores/escritores à espera
            if (rwq.Count > 0)
            {
                //Se houver leitores à espera
                if (rwq.First.Value.rw == READER)
                {
                    //Notificar todos os leitores que estão no inicio da fila, antes de uma escrita
                    NotifyAllReaders();
                }
                //Se houver escritores à espera
                else
                {
                    //Notifica o primeiro escritor da lista
                    SyncUtils.Notify(lockObj, rwq.First);
                }
            }
        }
    }
Example #2
0
 //Acedido na posse do lock - lockObj
 private void NotifyAllReaders()
 {
     for (LinkedListNode <Rw> curr = rwq.First; ; curr = curr.Next)
     {
         if (curr.Value.rw == WRITER)
         {
             return;
         }
         SyncUtils.Notify(lockObj, curr);
     }
 }
Example #3
0
 public void Leave(int key)
 {
     lock (map)
     {
         //Se não existe a key, retorna e não faz nada
         if (!map.ContainsKey(key))
         {
             return;
         }
         //Região associada à key
         Region r = map[key];
         //menos uma thread dentro da região
         r.inside--;
         //se houver threads à espera para entrar na região
         if (r.waiting.Count > 0)
         {
             //É notificada a primeira que entrou para cumprir a disciplina FIFO
             SyncUtils.Notify(map, r.waiting.First);
         }
     }
 }
Example #4
0
    // throws InvalidOperationException
    public void UpRead()
    {
        lock (lockObj)
        {
            if (!readersInside.Contains(Thread.CurrentThread.ManagedThreadId))
            {
                throw new InvalidOperationException();
            }

            //Menos um leitor a ler
            readersReading--;
            readersInside.Remove(Thread.CurrentThread.ManagedThreadId);

            //Se não esta nenhum leitor a ler e houver escritores à espera
            //Não pode haver leitores à espera no inicio da fila neste momento!!
            if (readersReading == 0 && rwq.Count > 0)
            {
                //Notifica o primeiro escritor da lista
                SyncUtils.Notify(lockObj, rwq.First);
            }
        }
    }