/* ================================================================================ RPL/2 (R) version 4.1.5 Copyright (C) 1989-2011 Dr. BERTRAND Joël This file is part of RPL/2. RPL/2 is free software; you can redistribute it and/or modify it under the terms of the CeCILL V2 License as published by the french CEA, CNRS and INRIA. RPL/2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License for more details. You should have received a copy of the CeCILL License along with RPL/2. If not, write to info@cecill.info. ================================================================================ */ #include "rpl-conv.h" /* ================================================================================ Fonction 'poll' ================================================================================ Entrées : pointeur sur une structure struct_processus -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_poll(struct_processus *s_etat_processus) { int erreur; int ios; int timeout; logical1 drapeau; struct_liste_chainee *l_element_courant; struct_objet *s_objet_argument_1; struct_objet *s_objet_argument_2; struct_objet *s_objet_argument_3; struct_objet *s_objet_resultat; struct pollfd s_poll; unsigned char *registre; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n POLL "); if ((*s_etat_processus).langue == 'F') { printf("(attente d'un événement sur un fichier ou une socket)\n\n"); } else { printf("(wait for event on file or socket)\n\n"); } if ((*s_etat_processus).langue == 'F') { printf(" Utilisation :\n\n"); } else { printf(" Usage:\n\n"); } printf(" FILE { \"POLLIN\" \"POLLOUT\" } TIMEOUT POLL\n\n"); printf(" 3: %s, %s\n", d_SCK, d_FCH); printf(" 2: %s\n", d_LST); printf(" 1: %s, %s\n", d_INT, d_REL); printf("-> 1: %s\n", d_INT); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 3) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_1) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_2) == d_erreur) { liberation(s_etat_processus, s_objet_argument_1); (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_3) == d_erreur) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (((*s_objet_argument_3).type == SCK) || ((*s_objet_argument_3).type == FCH)) { if ((*s_objet_argument_3).type == SCK) { s_poll.fd = (*((struct_socket *) (*s_objet_argument_3).objet)).socket; } else { s_poll.fd = (*((struct_fichier *) (*s_objet_argument_3).objet)).descripteur; } if ((*s_objet_argument_2).type != LST) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } l_element_courant = (*s_objet_argument_2).objet; s_poll.events = 0; while(l_element_courant != NULL) { if ((*(*l_element_courant).donnee).type != CHN) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } if ((registre = conversion_majuscule((unsigned char *) (*(*l_element_courant).donnee).objet)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (strcmp(registre, "POLLIN") == 0) { s_poll.events |= POLLIN; } else if (strcmp(registre, "POLLOUT") == 0) { s_poll.events |= POLLOUT; } else { free(registre); liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); (*s_etat_processus).erreur_execution = d_ex_erreur_parametre_fichier; return; } free(registre); l_element_courant = (*l_element_courant).suivant; } s_poll.revents = 0; if ((*s_objet_argument_1).type == INT) { timeout = (*((integer8 *) (*s_objet_argument_1).objet)) * 1000L; } else if ((*s_objet_argument_1).type == REL) { timeout = (int) ((*((real8 *) (*s_objet_argument_1).objet)) * 1000L); } else { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } do { drapeau = d_vrai; # ifndef SEMAPHORES_NOMMES if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) # else if (sem_post((*s_etat_processus).semaphore_fork) != 0) # endif { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if ((ios = poll(&s_poll, 1, timeout)) < 0) { erreur = errno; # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus) .semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus).semaphore_fork) != 0) # endif if (erreur != EINTR) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); (*s_etat_processus).erreur_execution = d_ex_erreur_acces_fichier; return; } scrutation_injection(s_etat_processus); if ((*s_etat_processus).var_volatile_requete_arret != 0) { drapeau = d_vrai; } else { drapeau = d_faux; } } else { # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus) .semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus).semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } } } while(drapeau == d_faux); if ((s_objet_resultat = allocation(s_etat_processus, INT)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (ios > 0) { // Sortie sur un événement (*((integer8 *) (*s_objet_resultat).objet)) = -1; } else { // Sortie sur timeout (*((integer8 *) (*s_objet_resultat).objet)) = 0; } liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat) == d_erreur) { return; } } else { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } return; } // vim: ts=4