/// <summary> /// Método responsável por retirar da lista todos os semáforos que existem para que um nova seja criada. /// </summary> /// <param name="oidCronograma">Oid do cronograma</param> /// <param name="excluirSemaforos">Atributo que autoriza a exclusão de todos os semáforos.</param> public static void ExcluirSemaforosInativosPorCronograma(Guid oidCronograma, bool excluirSemaforos) { if (excluirSemaforos) { if (semaforosPorCronograma.ContainsKey(oidCronograma)) { //lock na lista de semáforos daquele cronograma para que nenhuma outra thread adicione mais semáforos a esta lista. lock (semaforosPorCronograma[oidCronograma].semaforos) { if (semaforosPorCronograma[oidCronograma].semaforos.Count > 0) { semaforosPorCronograma[oidCronograma] = new SemaforosControle() { lockerSemaforos = new ReaderWriterLockSlim(), semaforos = new List <SemaforoPorIntervalo>() } } ; } } } }
/// <summary> /// Método responsável por consultar os semáforos que uma determinada thread de reordenação deverá esperar para então executar sua própria reordenação. /// </summary> /// <param name="oidCronograma">Oid do cronograma (índice do dicionário de cronogramas)</param> /// <param name="inicio">Início do intervalo</param> /// <param name="final">Final do intervalo</param> /// <returns>Retorna uma lista contendo os semáforos que deve-se esperar</returns> public Hashtable ConsultarSemaforosImpactadosPorCronograma(Guid oidCronograma, short inicio, short final, Hashtable semaforos) { List <SemaforoPorIntervalo> semaforosImpactadosAguardar = new List <SemaforoPorIntervalo>(); List <SemaforoPorIntervalo> semaforosImpactadosNovos = new List <SemaforoPorIntervalo>(); lock (semaforosPorCronograma[oidCronograma].semaforos) { EsperarLeituraSemaforos(oidCronograma); if (semaforosPorCronograma[oidCronograma].semaforos.Count == 0) { semaforosImpactadosNovos.Add(new SemaforoPorIntervalo(inicio, final)); } else { for (int i = 0; i < semaforosPorCronograma[oidCronograma].semaforos.Count; i++) { SemaforoPorIntervalo.VerificarSemaforosImpactados(ref semaforosImpactadosAguardar, ref semaforosImpactadosNovos, ref semaforosImpactadosNovos, semaforosPorCronograma[oidCronograma].semaforos[i], inicio, final); if (semaforosImpactadosNovos.Count > 0) { if (semaforosImpactadosAguardar.Count > 0) { for (int indice = 0; indice < semaforosImpactadosAguardar.Count; indice++) { SemaforoPorIntervalo.DecrementarContadorSemaforoEmEspera(semaforosImpactadosAguardar[indice]); } } break; } } } LiberarLeituraSemaforos(oidCronograma); if (semaforosImpactadosNovos.Count > 0) { EsperarEscritaSemaforos(oidCronograma); semaforosImpactadosAguardar.Clear(); semaforosImpactadosNovos.Clear(); List <SemaforoPorIntervalo> semaforosExistentes = semaforosPorCronograma[oidCronograma].semaforos; if (semaforosPorCronograma[oidCronograma].semaforos.Count == 0) { SemaforoPorIntervalo novoSemaforo = new SemaforoPorIntervalo(inicio, final); semaforosPorCronograma[oidCronograma].semaforos.Add(novoSemaforo); semaforosImpactadosNovos.Add(novoSemaforo); } else { for (int i = 0; i < semaforosPorCronograma[oidCronograma].semaforos.Count; i++) { if (semaforosPorCronograma[oidCronograma].semaforos[i].semaforo != null) { SemaforoPorIntervalo.IncrementarContadorSemaforoEmEspera(semaforosPorCronograma[oidCronograma].semaforos[i]); SemaforoPorIntervalo.VerificarSemaforosImpactados(ref semaforosImpactadosAguardar, ref semaforosImpactadosNovos, ref semaforosExistentes, semaforosPorCronograma[oidCronograma].semaforos[i], inicio, final); SemaforoPorIntervalo.DecrementarContadorSemaforoEmEspera(semaforosPorCronograma[oidCronograma].semaforos[i]); } else { semaforosPorCronograma[oidCronograma] = new SemaforosControle() { lockerSemaforos = new ReaderWriterLockSlim(), semaforos = new List <SemaforoPorIntervalo>() }; //cria um semáforo SemaforoPorIntervalo novoSemaforo = new SemaforoPorIntervalo(inicio, final); semaforosImpactadosNovos.Add(novoSemaforo); semaforosPorCronograma[oidCronograma].semaforos.Add(novoSemaforo); } } } LiberarEscritaSemaforos(oidCronograma); } } semaforos.Add(SEMAFOROS_AGUARDAR, semaforosImpactadosAguardar); semaforos.Add(SEMAFOROS_NOVOS, semaforosImpactadosNovos); return(semaforos); }
/// <summary> /// Método responsável controlar o acesso de threads simultaneamente enquanto leem e escrevem tanto no dicionário de cronogramas quanto na lista de semáforos de cada cronograma. /// Valida o acesso por cronograma e intervalo. /// </summary> /// <param name="oidCronograma">Oid cronograma</param> /// <param name="inicio">Início do intervalo</param> /// <param name="final">Final do intervalo</param> public virtual Hashtable ControlarSemaforos(Guid oidCronograma, short inicio, short final) { Hashtable semaforos = new Hashtable(); ControlarIncrementacaoContadorAcessoPorCronograma(oidCronograma); ControlarExclusaoSemaforosInativosPorCronograma(oidCronograma); if (ValidarCronograma(oidCronograma)) { semaforos = ConsultarSemaforosImpactadosPorCronograma(oidCronograma, inicio, final, semaforos); ControlarExclusaoCronogramasInexistentes(); } else { EsperarEscritaCronogramas(); if (semaforosPorCronograma.ContainsKey(oidCronograma)) { LiberarEscritaCronogramas(); semaforos = ConsultarSemaforosImpactadosPorCronograma(oidCronograma, inicio, final, semaforos); ControlarExclusaoCronogramasInexistentes(); ControlarDecrementacaoContadorAcessoPorCronograma(oidCronograma); return(semaforos); } else { //cria um objeto SemaforoPorCronograma que armazena um semáforo e a lista de semáforos de um cronograma SemaforosControle semaforosControle = new SemaforosControle() { lockerSemaforos = new ReaderWriterLockSlim(), semaforos = new List <SemaforoPorIntervalo>() }; //cria um semáforo SemaforoPorIntervalo novoSemaforo = new SemaforoPorIntervalo(inicio, final); //cria uma lista para retornar na Hash List <SemaforoPorIntervalo> semaforosNovos = new List <SemaforoPorIntervalo>(); semaforosNovos.Add(novoSemaforo); //Adiciona o semáforo novo criado para retornar na hash semaforos.Add(SEMAFOROS_NOVOS, semaforosNovos); //adiciona o semáforo à lista de semáforo por cronograma. semaforosControle.semaforos.Add(novoSemaforo); //adiciona o cronograma e sua lista ao dicionário de cronogramas ativos. semaforosPorCronograma.Add(oidCronograma, semaforosControle); } ControlarExclusaoCronogramasInexistentes(); LiberarEscritaCronogramas(); } ControlarDecrementacaoContadorAcessoPorCronograma(oidCronograma); return(semaforos); }