![]() ![]() | ![]() |
Ajout du support des sockets non formatées.
1: /* 2: ================================================================================ 3: RPL/2 (R) version 4.1.13 4: Copyright (C) 1989-2013 Dr. BERTRAND Joël 5: 6: This file is part of RPL/2. 7: 8: RPL/2 is free software; you can redistribute it and/or modify it 9: under the terms of the CeCILL V2 License as published by the french 10: CEA, CNRS and INRIA. 11: 12: RPL/2 is distributed in the hope that it will be useful, but WITHOUT 13: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License 15: for more details. 16: 17: You should have received a copy of the CeCILL License 18: along with RPL/2. If not, write to info@cecill.info. 19: ================================================================================ 20: */ 21: 22: 23: #include "rpl-conv.h" 24: 25: 26: /* 27: ================================================================================ 28: Procédures de gestion par thread des variables issues des gestionnaires 29: de signaux 30: ================================================================================ 31: Entrée : variable globale 32: -------------------------------------------------------------------------------- 33: Sortie : variable globale modifiée 34: -------------------------------------------------------------------------------- 35: Effets de bord : néant 36: ================================================================================ 37: */ 38: 39: typedef struct thread 40: { 41: pid_t pid; 42: pthread_t tid; 43: 44: logical1 thread_principal; 45: 46: struct_processus *s_etat_processus; 47: } struct_thread; 48: 49: typedef struct liste_chainee_volatile 50: { 51: volatile struct liste_chainee_volatile *suivant; 52: volatile void *donnee; 53: } struct_liste_chainee_volatile; 54: 55: static volatile struct_liste_chainee_volatile *liste_threads 56: = NULL; 57: static volatile struct_liste_chainee_volatile *liste_threads_surveillance 58: = NULL; 59: static volatile int code_erreur_gsl = 0; 60: 61: unsigned char *racine_segment; 62: 63: static pthread_mutex_t mutex_interruptions 64: = PTHREAD_MUTEX_INITIALIZER; 65: 66: static void * 67: thread_surveillance_signaux(void *argument) 68: { 69: // Cette fonction est lancée dans un thread créé par processus pour 70: // gérer le cas des appels système qui seraient bloqués lors de l'arrivée du 71: // signal SIGALRM. Les processus externes n'envoient plus un signal au 72: // processus ou au thread à signaler mais positionnent les informations 73: // nécessaires dans la queue des signaux et incrémentent le sémaphore. 74: // Le sémaphore est décrémenté lorsque le signal est effectivement traité. 75: 76: int nombre_signaux_envoyes; 77: 78: struct_processus *s_etat_processus; 79: 80: struct timespec attente; 81: 82: volatile struct_liste_chainee_volatile *l_element_courant; 83: 84: sigset_t set; 85: 86: sigfillset(&set); 87: pthread_sigmask(SIG_BLOCK, &set, NULL); 88: 89: s_etat_processus = (struct_processus *) argument; 90: 91: for(;;) 92: { 93: attente.tv_sec = 0; 94: attente.tv_nsec = GRANULARITE_us * 1000; 95: 96: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 97: if (sem_wait(&(*s_queue_signaux).signalisation) == 0) 98: # else 99: if (sem_wait(semaphore_signalisation) == 0) 100: # endif 101: { 102: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 103: sem_post(&(*s_queue_signaux).signalisation); 104: # else 105: sem_post(semaphore_signalisation); 106: # endif 107: 108: if ((*s_queue_signaux).requete_arret == d_vrai) 109: { 110: break; 111: } 112: 113: nombre_signaux_envoyes = 0; 114: sched_yield(); 115: 116: // Dans un premier temps, on verrouille la queue des signaux 117: // affectée au processus courant pour vérifier s'il y a quelque 118: // chose à traiter. 119: 120: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 121: sem_wait(&(*s_queue_signaux).semaphore); 122: # else 123: sem_wait(semaphore_queue_signaux); 124: # endif 125: 126: if ((*s_queue_signaux).pointeur_lecture != 127: (*s_queue_signaux).pointeur_ecriture) 128: { 129: // Attention : raise() envoit le signal au thread appelant ! 130: // kill() l'envoie au processus appelant, donc dans notre 131: // cas à un thread aléatoire du processus, ce qui nous 132: // convient tout à fait puisqu'il s'agit de débloquer les 133: // appels système lents. 134: 135: nombre_signaux_envoyes++; 136: kill(getpid(), SIGALRM); 137: } 138: 139: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 140: sem_post(&(*s_queue_signaux).semaphore); 141: # else 142: sem_post(semaphore_queue_signaux); 143: # endif 144: 145: // Dans un second temps, on balaye toutes les queues de signaux 146: // des threads du processus courant. 147: 148: pthread_mutex_lock(&mutex_liste_threads); 149: l_element_courant = liste_threads; 150: 151: while(l_element_courant != NULL) 152: { 153: if ((*((struct_thread *) (*l_element_courant).donnee)).pid 154: == getpid()) 155: { 156: if ((*(*((struct_thread *) (*l_element_courant).donnee)) 157: .s_etat_processus).pointeur_signal_ecriture != 158: (*(*((struct_thread *) (*l_element_courant).donnee)) 159: .s_etat_processus).pointeur_signal_lecture) 160: { 161: nombre_signaux_envoyes++; 162: pthread_kill((*((struct_thread *) (*l_element_courant) 163: .donnee)).tid, SIGALRM); 164: } 165: } 166: 167: l_element_courant = (*l_element_courant).suivant; 168: } 169: 170: pthread_mutex_unlock(&mutex_liste_threads); 171: 172: // Nanosleep 173: 174: if (nombre_signaux_envoyes > 0) 175: { 176: nanosleep(&attente, NULL); 177: } 178: } 179: else 180: { 181: if (errno != EINTR) 182: { 183: (*s_etat_processus).erreur_systeme = d_es_processus; 184: } 185: } 186: } 187: 188: pthread_exit(NULL); 189: } 190: 191: void 192: modification_pid_thread_pere(struct_processus *s_etat_processus) 193: { 194: // La variable existe toujours et aucun thread concurrent ne peut 195: // la modifier puisque cette routine ne peut être appelée que depuis 196: // DAEMON. 197: 198: (*((struct_thread *) (*liste_threads).donnee)).pid = 199: (*s_etat_processus).pid_processus_pere; 200: 201: return; 202: } 203: 204: void 205: insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal) 206: { 207: volatile struct_liste_chainee_volatile *l_nouvel_objet; 208: 209: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile))) 210: == NULL) 211: { 212: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 213: return; 214: } 215: 216: if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL) 217: { 218: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 219: return; 220: } 221: 222: (*((struct_thread *) (*l_nouvel_objet).donnee)).pid = getpid(); 223: (*((struct_thread *) (*l_nouvel_objet).donnee)).tid = pthread_self(); 224: (*((struct_thread *) (*l_nouvel_objet).donnee)).thread_principal = 225: thread_principal; 226: (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus = 227: s_etat_processus; 228: 229: if (pthread_mutex_lock(&mutex_liste_threads) != 0) 230: { 231: (*s_etat_processus).erreur_systeme = d_es_processus; 232: return; 233: } 234: 235: (*l_nouvel_objet).suivant = liste_threads; 236: liste_threads = l_nouvel_objet; 237: 238: if (pthread_mutex_unlock(&mutex_liste_threads) != 0) 239: { 240: (*s_etat_processus).erreur_systeme = d_es_processus; 241: return; 242: } 243: 244: return; 245: } 246: 247: void 248: insertion_thread_surveillance(struct_processus *s_etat_processus, 249: struct_descripteur_thread *s_argument_thread) 250: { 251: volatile struct_liste_chainee_volatile *l_nouvel_objet; 252: 253: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile))) 254: == NULL) 255: { 256: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 257: return; 258: } 259: 260: if (pthread_mutex_lock(&mutex_liste_threads) != 0) 261: { 262: (*s_etat_processus).erreur_systeme = d_es_processus; 263: return; 264: } 265: 266: pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references)); 267: (*s_argument_thread).nombre_references++; 268: pthread_mutex_unlock(&((*s_argument_thread).mutex_nombre_references)); 269: 270: (*l_nouvel_objet).suivant = liste_threads_surveillance; 271: (*l_nouvel_objet).donnee = (void *) s_argument_thread; 272: 273: liste_threads_surveillance = l_nouvel_objet; 274: 275: if (pthread_mutex_unlock(&mutex_liste_threads) != 0) 276: { 277: (*s_etat_processus).erreur_systeme = d_es_processus; 278: return; 279: } 280: 281: return; 282: } 283: 284: void 285: retrait_thread(struct_processus *s_etat_processus) 286: { 287: volatile struct_liste_chainee_volatile *l_element_precedent; 288: volatile struct_liste_chainee_volatile *l_element_courant; 289: 290: if (pthread_mutex_lock(&mutex_liste_threads) != 0) 291: { 292: (*s_etat_processus).erreur_systeme = d_es_processus; 293: return; 294: } 295: 296: l_element_precedent = NULL; 297: l_element_courant = liste_threads; 298: 299: while(l_element_courant != NULL) 300: { 301: if (((*((struct_thread *) (*l_element_courant).donnee)).pid 302: == getpid()) && (pthread_equal((*((struct_thread *) 303: (*l_element_courant).donnee)).tid, pthread_self()) != 0)) 304: { 305: break; 306: } 307: 308: l_element_precedent = l_element_courant; 309: l_element_courant = (*l_element_courant).suivant; 310: } 311: 312: if (l_element_courant == NULL) 313: { 314: pthread_mutex_unlock(&mutex_liste_threads); 315: (*s_etat_processus).erreur_systeme = d_es_processus; 316: return; 317: } 318: 319: if (l_element_precedent == NULL) 320: { 321: liste_threads = (*l_element_courant).suivant; 322: } 323: else 324: { 325: (*l_element_precedent).suivant = (*l_element_courant).suivant; 326: } 327: 328: if (pthread_mutex_unlock(&mutex_liste_threads) != 0) 329: { 330: (*s_etat_processus).erreur_systeme = d_es_processus; 331: return; 332: } 333: 334: // Le thread ne peut plus traiter de signaux explicites. Il convient 335: // alors de corriger le sémaphore pour annuler les signaux en attente. 336: 337: while((*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus) 338: .pointeur_signal_ecriture != (*(*((struct_thread *) 339: (*l_element_courant).donnee)).s_etat_processus) 340: .pointeur_signal_lecture) 341: { 342: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 343: while(sem_wait(&((*s_queue_signaux).signalisation)) != 0) 344: # else 345: while(sem_wait(semaphore_signalisation) != 0) 346: # endif 347: { 348: if (errno != EINTR) 349: { 350: (*s_etat_processus).erreur_systeme = d_es_processus; 351: return; 352: } 353: } 354: 355: (*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus) 356: .pointeur_signal_lecture = ((*(*((struct_thread *) 357: (*l_element_courant).donnee)).s_etat_processus) 358: .pointeur_signal_lecture + 1) % LONGUEUR_QUEUE_SIGNAUX; 359: } 360: 361: free((void *) (*l_element_courant).donnee); 362: free((struct_liste_chainee_volatile *) l_element_courant); 363: 364: return; 365: } 366: 367: void 368: retrait_thread_surveillance(struct_processus *s_etat_processus, 369: struct_descripteur_thread *s_argument_thread) 370: { 371: volatile struct_liste_chainee_volatile *l_element_precedent; 372: volatile struct_liste_chainee_volatile *l_element_courant; 373: 374: if (pthread_mutex_lock(&mutex_liste_threads) != 0) 375: { 376: (*s_etat_processus).erreur_systeme = d_es_processus; 377: return; 378: } 379: 380: l_element_precedent = NULL; 381: l_element_courant = liste_threads_surveillance; 382: 383: while(l_element_courant != NULL) 384: { 385: if ((*l_element_courant).donnee == (void *) s_argument_thread) 386: { 387: break; 388: } 389: 390: l_element_precedent = l_element_courant; 391: l_element_courant = (*l_element_courant).suivant; 392: } 393: 394: if (l_element_courant == NULL) 395: { 396: pthread_mutex_unlock(&mutex_liste_threads); 397: (*s_etat_processus).erreur_systeme = d_es_processus; 398: return; 399: } 400: 401: if (l_element_precedent == NULL) 402: { 403: liste_threads_surveillance = (*l_element_courant).suivant; 404: } 405: else 406: { 407: (*l_element_precedent).suivant = (*l_element_courant).suivant; 408: } 409: 410: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references)) 411: != 0) 412: { 413: pthread_mutex_unlock(&mutex_liste_threads); 414: (*s_etat_processus).erreur_systeme = d_es_processus; 415: return; 416: } 417: 418: (*s_argument_thread).nombre_references--; 419: 420: BUG((*s_argument_thread).nombre_references < 0, 421: printf("(*s_argument_thread).nombre_references = %d\n", 422: (int) (*s_argument_thread).nombre_references)); 423: 424: if ((*s_argument_thread).nombre_references == 0) 425: { 426: if (pthread_mutex_unlock(&((*s_argument_thread) 427: .mutex_nombre_references)) != 0) 428: { 429: pthread_mutex_unlock(&mutex_liste_threads); 430: (*s_etat_processus).erreur_systeme = d_es_processus; 431: return; 432: } 433: 434: pthread_mutex_destroy(&((*s_argument_thread).mutex)); 435: pthread_mutex_destroy(&((*s_argument_thread).mutex_nombre_references)); 436: free(s_argument_thread); 437: } 438: else 439: { 440: if (pthread_mutex_unlock(&((*s_argument_thread) 441: .mutex_nombre_references)) != 0) 442: { 443: pthread_mutex_unlock(&mutex_liste_threads); 444: (*s_etat_processus).erreur_systeme = d_es_processus; 445: return; 446: } 447: } 448: 449: if (pthread_mutex_unlock(&mutex_liste_threads) != 0) 450: { 451: (*s_etat_processus).erreur_systeme = d_es_processus; 452: return; 453: } 454: 455: free((struct_liste_chainee_volatile *) l_element_courant); 456: return; 457: } 458: 459: void 460: verrouillage_threads_concurrents(struct_processus *s_etat_processus) 461: { 462: volatile struct_liste_chainee_volatile *l_element_courant; 463: 464: if (pthread_mutex_lock(&mutex_liste_threads) != 0) 465: { 466: (*s_etat_processus).erreur_systeme = d_es_processus; 467: return; 468: } 469: 470: l_element_courant = liste_threads; 471: 472: while(l_element_courant != NULL) 473: { 474: if (((*((struct_thread *) (*l_element_courant).donnee)).pid 475: == getpid()) && (pthread_equal((*((struct_thread *) 476: (*l_element_courant).donnee)).tid, pthread_self()) == 0)) 477: { 478: # ifndef SEMAPHORES_NOMMES 479: while(sem_wait(&((*(*((struct_thread *) (*l_element_courant) 480: .donnee)).s_etat_processus).semaphore_fork)) == -1) 481: # else 482: while(sem_wait((*(*((struct_thread *) (*l_element_courant) 483: .donnee)).s_etat_processus).semaphore_fork) == -1) 484: # endif 485: { 486: (*s_etat_processus).erreur_systeme = d_es_processus; 487: return; 488: } 489: } 490: 491: l_element_courant = (*l_element_courant).suivant; 492: } 493: 494: return; 495: } 496: 497: void 498: deverrouillage_threads_concurrents(struct_processus *s_etat_processus) 499: { 500: volatile struct_liste_chainee_volatile *l_element_courant; 501: 502: l_element_courant = liste_threads; 503: 504: while(l_element_courant != NULL) 505: { 506: if (((*((struct_thread *) (*l_element_courant).donnee)).pid 507: == getpid()) && (pthread_equal((*((struct_thread *) 508: (*l_element_courant).donnee)).tid, pthread_self()) == 0)) 509: { 510: # ifndef SEMAPHORES_NOMMES 511: if (sem_post(&((*(*((struct_thread *) 512: (*l_element_courant).donnee)).s_etat_processus) 513: .semaphore_fork)) != 0) 514: # else 515: if (sem_post((*(*((struct_thread *) 516: (*l_element_courant).donnee)).s_etat_processus) 517: .semaphore_fork) != 0) 518: # endif 519: { 520: if (pthread_mutex_unlock(&mutex_liste_threads) != 0) 521: { 522: (*s_etat_processus).erreur_systeme = d_es_processus; 523: return; 524: } 525: 526: (*s_etat_processus).erreur_systeme = d_es_processus; 527: return; 528: } 529: } 530: 531: l_element_courant = (*l_element_courant).suivant; 532: } 533: 534: if (pthread_mutex_unlock(&mutex_liste_threads) != 0) 535: { 536: (*s_etat_processus).erreur_systeme = d_es_processus; 537: return; 538: } 539: 540: return; 541: } 542: 543: void 544: liberation_threads(struct_processus *s_etat_processus) 545: { 546: logical1 suppression_variables_partagees; 547: 548: struct_descripteur_thread *s_argument_thread; 549: 550: struct_processus *candidat; 551: 552: struct_liste_variables_partagees *l_element_partage_courant; 553: struct_liste_variables_partagees *l_element_partage_suivant; 554: 555: struct_liste_variables_statiques *l_element_statique_courant; 556: struct_liste_variables_statiques *l_element_statique_suivant; 557: 558: unsigned long i; 559: 560: void *element_candidat; 561: void *element_courant; 562: void *element_suivant; 563: 564: volatile struct_liste_chainee_volatile *l_element_courant; 565: volatile struct_liste_chainee_volatile *l_element_suivant; 566: 567: if (pthread_mutex_lock(&mutex_liste_threads) == -1) 568: { 569: (*s_etat_processus).erreur_systeme = d_es_processus; 570: return; 571: } 572: 573: l_element_courant = liste_threads; 574: suppression_variables_partagees = d_faux; 575: 576: while(l_element_courant != NULL) 577: { 578: if ((*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus 579: != s_etat_processus) 580: { 581: candidat = s_etat_processus; 582: s_etat_processus = (*((struct_thread *) 583: (*l_element_courant).donnee)).s_etat_processus; 584: free((*s_etat_processus).localisation); 585: 586: // (*s_etat_processus).instruction_courante peut pointer sur 587: // n'importe quoi (une instruction courante ou un champ d'une 588: // structure objet). On ne le libère pas quitte à avoir une 589: // petite fuite mémoire dans le processus fils. 590: 591: if ((*s_etat_processus).instruction_courante != NULL) 592: { 593: //free((*s_etat_processus).instruction_courante); 594: } 595: 596: close((*s_etat_processus).pipe_acquittement); 597: close((*s_etat_processus).pipe_donnees); 598: close((*s_etat_processus).pipe_injections); 599: close((*s_etat_processus).pipe_nombre_injections); 600: close((*s_etat_processus).pipe_interruptions); 601: close((*s_etat_processus).pipe_nombre_objets_attente); 602: close((*s_etat_processus).pipe_nombre_interruptions_attente); 603: 604: liberation(s_etat_processus, (*s_etat_processus).at_exit); 605: 606: if ((*s_etat_processus).nom_fichier_impression != NULL) 607: { 608: free((*s_etat_processus).nom_fichier_impression); 609: } 610: 611: while((*s_etat_processus).fichiers_graphiques != NULL) 612: { 613: free((*(*s_etat_processus).fichiers_graphiques).nom); 614: 615: if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL) 616: { 617: free((*(*s_etat_processus).fichiers_graphiques).legende); 618: } 619: 620: element_courant = (*s_etat_processus).fichiers_graphiques; 621: (*s_etat_processus).fichiers_graphiques = 622: (*(*s_etat_processus).fichiers_graphiques).suivant; 623: 624: free(element_courant); 625: } 626: 627: if ((*s_etat_processus).entree_standard != NULL) 628: { 629: pclose((*s_etat_processus).entree_standard); 630: } 631: 632: if ((*s_etat_processus).generateur_aleatoire != NULL) 633: { 634: liberation_generateur_aleatoire(s_etat_processus); 635: } 636: 637: if ((*s_etat_processus).instruction_derniere_erreur != NULL) 638: { 639: free((*s_etat_processus).instruction_derniere_erreur); 640: (*s_etat_processus).instruction_derniere_erreur = NULL; 641: } 642: 643: element_courant = (void *) (*s_etat_processus) 644: .l_base_pile_processus; 645: while(element_courant != NULL) 646: { 647: s_argument_thread = (struct_descripteur_thread *) 648: (*((struct_liste_chainee *) element_courant)).donnee; 649: 650: if (pthread_mutex_lock(&((*s_argument_thread) 651: .mutex_nombre_references)) != 0) 652: { 653: (*s_etat_processus).erreur_systeme = d_es_processus; 654: pthread_mutex_unlock(&mutex_liste_threads); 655: return; 656: } 657: 658: (*s_argument_thread).nombre_references--; 659: 660: BUG((*s_argument_thread).nombre_references < 0, 661: printf("(*s_argument_thread).nombre_references = %d\n", 662: (int) (*s_argument_thread).nombre_references)); 663: 664: if ((*s_argument_thread).nombre_references == 0) 665: { 666: close((*s_argument_thread).pipe_objets[0]); 667: close((*s_argument_thread).pipe_acquittement[1]); 668: close((*s_argument_thread).pipe_injections[1]); 669: close((*s_argument_thread).pipe_nombre_injections[1]); 670: close((*s_argument_thread).pipe_nombre_objets_attente[0]); 671: close((*s_argument_thread).pipe_interruptions[0]); 672: close((*s_argument_thread) 673: .pipe_nombre_interruptions_attente[0]); 674: 675: if (pthread_mutex_unlock(&((*s_argument_thread) 676: .mutex_nombre_references)) != 0) 677: { 678: (*s_etat_processus).erreur_systeme = d_es_processus; 679: pthread_mutex_unlock(&mutex_liste_threads); 680: return; 681: } 682: 683: pthread_mutex_destroy(&((*s_argument_thread).mutex)); 684: pthread_mutex_destroy(&((*s_argument_thread) 685: .mutex_nombre_references)); 686: 687: if ((*s_argument_thread).processus_detache == d_faux) 688: { 689: if ((*s_argument_thread).destruction_objet == d_vrai) 690: { 691: liberation(s_etat_processus, (*s_argument_thread) 692: .argument); 693: } 694: } 695: 696: free(s_argument_thread); 697: } 698: else 699: { 700: if (pthread_mutex_unlock(&((*s_argument_thread) 701: .mutex_nombre_references)) != 0) 702: { 703: (*s_etat_processus).erreur_systeme = d_es_processus; 704: pthread_mutex_unlock(&mutex_liste_threads); 705: return; 706: } 707: } 708: 709: element_suivant = (*((struct_liste_chainee *) element_courant)) 710: .suivant; 711: free(element_courant); 712: element_courant = element_suivant; 713: } 714: 715: (*s_etat_processus).l_base_pile_processus = NULL; 716: 717: pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex)); 718: pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex)); 719: liberation(s_etat_processus, (*s_etat_processus).indep); 720: 721: pthread_mutex_trylock(&((*(*s_etat_processus).depend).mutex)); 722: pthread_mutex_unlock(&((*(*s_etat_processus).depend).mutex)); 723: liberation(s_etat_processus, (*s_etat_processus).depend); 724: 725: free((*s_etat_processus).label_x); 726: free((*s_etat_processus).label_y); 727: free((*s_etat_processus).label_z); 728: free((*s_etat_processus).titre); 729: free((*s_etat_processus).legende); 730: 731: pthread_mutex_trylock(&((*(*s_etat_processus) 732: .parametres_courbes_de_niveau).mutex)); 733: pthread_mutex_unlock(&((*(*s_etat_processus) 734: .parametres_courbes_de_niveau).mutex)); 735: liberation(s_etat_processus, (*s_etat_processus) 736: .parametres_courbes_de_niveau); 737: 738: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++) 739: { 740: if ((*s_etat_processus).corps_interruptions[i] != NULL) 741: { 742: pthread_mutex_trylock(&((*(*s_etat_processus) 743: .corps_interruptions[i]).mutex)); 744: pthread_mutex_unlock(&((*(*s_etat_processus) 745: .corps_interruptions[i]).mutex)); 746: 747: liberation(s_etat_processus, 748: (*s_etat_processus).corps_interruptions[i]); 749: } 750: 751: element_courant = (*s_etat_processus) 752: .pile_origine_interruptions[i]; 753: 754: while(element_courant != NULL) 755: { 756: element_suivant = (*((struct_liste_chainee *) 757: element_courant)).suivant; 758: 759: pthread_mutex_trylock(&((*(*((struct_liste_chainee *) 760: element_courant)).donnee).mutex)); 761: pthread_mutex_unlock(&((*(*((struct_liste_chainee *) 762: element_courant)).donnee).mutex)); 763: 764: liberation(s_etat_processus, 765: (*((struct_liste_chainee *) element_courant)) 766: .donnee); 767: free(element_courant); 768: 769: element_courant = element_suivant; 770: } 771: } 772: 773: // ne peut être effacé qu'une seule fois 774: if (suppression_variables_partagees == d_faux) 775: { 776: suppression_variables_partagees = d_vrai; 777: 778: liberation_arbre_variables_partagees(s_etat_processus, 779: (*(*s_etat_processus).s_arbre_variables_partagees)); 780: 781: l_element_partage_courant = (*(*s_etat_processus) 782: .l_liste_variables_partagees); 783: 784: while(l_element_partage_courant != NULL) 785: { 786: l_element_partage_suivant = 787: (*l_element_partage_courant).suivant; 788: free(l_element_partage_courant); 789: l_element_partage_courant = l_element_partage_suivant; 790: } 791: } 792: 793: liberation_arbre_variables(s_etat_processus, 794: (*s_etat_processus).s_arbre_variables, d_faux); 795: 796: l_element_statique_courant = (*s_etat_processus) 797: .l_liste_variables_statiques; 798: 799: while(l_element_statique_courant != NULL) 800: { 801: l_element_statique_suivant = 802: (*l_element_statique_courant).suivant; 803: free(l_element_statique_courant); 804: l_element_statique_courant = l_element_statique_suivant; 805: } 806: 807: element_courant = (*s_etat_processus).l_base_pile; 808: while(element_courant != NULL) 809: { 810: element_suivant = (*((struct_liste_chainee *) 811: element_courant)).suivant; 812: 813: pthread_mutex_trylock(&((*(*((struct_liste_chainee *) 814: element_courant)).donnee).mutex)); 815: pthread_mutex_unlock(&((*(*((struct_liste_chainee *) 816: element_courant)).donnee).mutex)); 817: 818: liberation(s_etat_processus, 819: (*((struct_liste_chainee *) 820: element_courant)).donnee); 821: free((struct_liste_chainee *) element_courant); 822: 823: element_courant = element_suivant; 824: } 825: 826: element_courant = (*s_etat_processus).l_base_pile_contextes; 827: while(element_courant != NULL) 828: { 829: element_suivant = (*((struct_liste_chainee *) 830: element_courant)).suivant; 831: 832: pthread_mutex_trylock(&((*(*((struct_liste_chainee *) 833: element_courant)).donnee).mutex)); 834: pthread_mutex_unlock(&((*(*((struct_liste_chainee *) 835: element_courant)).donnee).mutex)); 836: liberation(s_etat_processus, (*((struct_liste_chainee *) 837: element_courant)).donnee); 838: free((struct_liste_chainee *) element_courant); 839: 840: element_courant = element_suivant; 841: } 842: 843: element_courant = (*s_etat_processus).l_base_pile_taille_contextes; 844: while(element_courant != NULL) 845: { 846: element_suivant = (*((struct_liste_chainee *) 847: element_courant)).suivant; 848: 849: pthread_mutex_trylock(&((*(*((struct_liste_chainee *) 850: element_courant)).donnee).mutex)); 851: pthread_mutex_unlock(&((*(*((struct_liste_chainee *) 852: element_courant)).donnee).mutex)); 853: liberation(s_etat_processus, 854: (*((struct_liste_chainee *) 855: element_courant)).donnee); 856: free((struct_liste_chainee *) element_courant); 857: 858: element_courant = element_suivant; 859: } 860: 861: for(i = 0; i < (*s_etat_processus).nombre_instructions_externes; 862: i++) 863: { 864: free((*s_etat_processus).s_instructions_externes[i].nom); 865: free((*s_etat_processus).s_instructions_externes[i] 866: .nom_bibliotheque); 867: } 868: 869: if ((*s_etat_processus).nombre_instructions_externes != 0) 870: { 871: free((*s_etat_processus).s_instructions_externes); 872: } 873: 874: element_courant = (*s_etat_processus).s_bibliotheques; 875: while(element_courant != NULL) 876: { 877: element_suivant = (*((struct_liste_chainee *) 878: element_courant)).suivant; 879: 880: element_candidat = (*candidat).s_bibliotheques; 881: while(element_candidat != NULL) 882: { 883: if (((*((struct_bibliotheque *) (*((struct_liste_chainee *) 884: element_courant)).donnee)) 885: .descripteur == (*((struct_bibliotheque *) 886: (*((struct_liste_chainee *) element_candidat)) 887: .donnee)).descripteur) && 888: ((*((struct_bibliotheque *) 889: (*((struct_liste_chainee *) element_courant)) 890: .donnee)).pid == (*((struct_bibliotheque *) 891: (*((struct_liste_chainee *) element_candidat)) 892: .donnee)).pid) && (pthread_equal( 893: (*((struct_bibliotheque *) 894: (*((struct_liste_chainee *) element_courant)) 895: .donnee)).tid, (*((struct_bibliotheque *) 896: (*((struct_liste_chainee *) element_candidat)) 897: .donnee)).tid) != 0)) 898: { 899: break; 900: } 901: 902: element_candidat = (*((struct_liste_chainee *) 903: element_candidat)).suivant; 904: } 905: 906: if (element_candidat == NULL) 907: { 908: dlclose((*((struct_bibliotheque *) 909: (*((struct_liste_chainee *) element_courant)) 910: .donnee)).descripteur); 911: } 912: 913: free((*((struct_bibliotheque *) 914: (*((struct_liste_chainee *) 915: element_courant)).donnee)).nom); 916: free((*((struct_liste_chainee *) element_courant)).donnee); 917: free(element_courant); 918: 919: element_courant = element_suivant; 920: } 921: 922: element_courant = (*s_etat_processus).l_base_pile_last; 923: while(element_courant != NULL) 924: { 925: element_suivant = (*((struct_liste_chainee *) 926: element_courant)).suivant; 927: 928: pthread_mutex_trylock(&((*(*((struct_liste_chainee *) 929: element_courant)).donnee).mutex)); 930: pthread_mutex_unlock(&((*(*((struct_liste_chainee *) 931: element_courant)).donnee).mutex)); 932: liberation(s_etat_processus, 933: (*((struct_liste_chainee *) element_courant)).donnee); 934: free(element_courant); 935: 936: element_courant = element_suivant; 937: } 938: 939: element_courant = (*s_etat_processus).l_base_pile_systeme; 940: while(element_courant != NULL) 941: { 942: element_suivant = (*((struct_liste_pile_systeme *) 943: element_courant)).suivant; 944: 945: if ((*((struct_liste_pile_systeme *) 946: element_courant)).indice_boucle != NULL) 947: { 948: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *) 949: element_courant)).indice_boucle).mutex)); 950: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *) 951: element_courant)).indice_boucle).mutex)); 952: } 953: 954: liberation(s_etat_processus, 955: (*((struct_liste_pile_systeme *) 956: element_courant)).indice_boucle); 957: 958: if ((*((struct_liste_pile_systeme *) 959: element_courant)).limite_indice_boucle != NULL) 960: { 961: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *) 962: element_courant)).limite_indice_boucle).mutex)); 963: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *) 964: element_courant)).limite_indice_boucle).mutex)); 965: } 966: 967: liberation(s_etat_processus, 968: (*((struct_liste_pile_systeme *) 969: element_courant)).limite_indice_boucle); 970: 971: if ((*((struct_liste_pile_systeme *) 972: element_courant)).objet_de_test != NULL) 973: { 974: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *) 975: element_courant)).objet_de_test).mutex)); 976: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *) 977: element_courant)).objet_de_test).mutex)); 978: } 979: 980: liberation(s_etat_processus, 981: (*((struct_liste_pile_systeme *) 982: element_courant)).objet_de_test); 983: 984: if ((*((struct_liste_pile_systeme *) 985: element_courant)).nom_variable != NULL) 986: { 987: free((*((struct_liste_pile_systeme *) 988: element_courant)).nom_variable); 989: } 990: 991: free(element_courant); 992: 993: element_courant = element_suivant; 994: } 995: 996: element_courant = (*s_etat_processus).s_fichiers; 997: while(element_courant != NULL) 998: { 999: element_suivant = (*((struct_liste_chainee *) 1000: element_courant)).suivant; 1001: 1002: element_candidat = (*candidat).s_fichiers; 1003: while(element_candidat != NULL) 1004: { 1005: if (((*((struct_descripteur_fichier *) 1006: (*((struct_liste_chainee *) element_courant)) 1007: .donnee)).pid == 1008: (*((struct_descripteur_fichier *) 1009: (*((struct_liste_chainee *) element_candidat)) 1010: .donnee)).pid) && (pthread_equal( 1011: (*((struct_descripteur_fichier *) 1012: (*((struct_liste_chainee *) element_courant)) 1013: .donnee)).tid, (*((struct_descripteur_fichier *) 1014: (*((struct_liste_chainee *) element_candidat)) 1015: .donnee)).tid) != 0)) 1016: { 1017: if ((*((struct_descripteur_fichier *) 1018: (*((struct_liste_chainee *) element_courant)) 1019: .donnee)).type == 1020: (*((struct_descripteur_fichier *) 1021: (*((struct_liste_chainee *) element_candidat)) 1022: .donnee)).type) 1023: { 1024: if ((*((struct_descripteur_fichier *) 1025: (*((struct_liste_chainee *) 1026: element_candidat)).donnee)).type == 'C') 1027: { 1028: if ((*((struct_descripteur_fichier *) 1029: (*((struct_liste_chainee *) 1030: element_courant)).donnee)) 1031: .descripteur_c == 1032: (*((struct_descripteur_fichier *) 1033: (*((struct_liste_chainee *) 1034: element_candidat)).donnee)) 1035: .descripteur_c) 1036: { 1037: break; 1038: } 1039: } 1040: else 1041: { 1042: if (((*((struct_descripteur_fichier *) 1043: (*((struct_liste_chainee *) 1044: element_courant)).donnee)) 1045: .descripteur_sqlite == 1046: (*((struct_descripteur_fichier *) 1047: (*((struct_liste_chainee *) 1048: element_candidat)).donnee)) 1049: .descripteur_sqlite) && 1050: ((*((struct_descripteur_fichier *) 1051: (*((struct_liste_chainee *) 1052: element_courant)).donnee)) 1053: .descripteur_c == 1054: (*((struct_descripteur_fichier *) 1055: (*((struct_liste_chainee *) 1056: element_candidat)).donnee)) 1057: .descripteur_c)) 1058: { 1059: break; 1060: } 1061: } 1062: } 1063: } 1064: 1065: element_candidat = (*((struct_liste_chainee *) 1066: element_candidat)).suivant; 1067: } 1068: 1069: if (element_candidat == NULL) 1070: { 1071: fclose((*((struct_descripteur_fichier *) 1072: (*((struct_liste_chainee *) element_courant)) 1073: .donnee)).descripteur_c); 1074: 1075: if ((*((struct_descripteur_fichier *) 1076: (*((struct_liste_chainee *) element_courant)) 1077: .donnee)).type != 'C') 1078: { 1079: sqlite3_close((*((struct_descripteur_fichier *) 1080: (*((struct_liste_chainee *) element_courant)) 1081: .donnee)).descripteur_sqlite); 1082: } 1083: } 1084: 1085: free((*((struct_descripteur_fichier *) 1086: (*((struct_liste_chainee *) 1087: element_courant)).donnee)).nom); 1088: free((struct_descripteur_fichier *) 1089: (*((struct_liste_chainee *) 1090: element_courant)).donnee); 1091: free(element_courant); 1092: 1093: element_courant = element_suivant; 1094: } 1095: 1096: element_courant = (*s_etat_processus).s_sockets; 1097: while(element_courant != NULL) 1098: { 1099: element_suivant = (*((struct_liste_chainee *) 1100: element_courant)).suivant; 1101: 1102: element_candidat = (*candidat).s_sockets; 1103: while(element_candidat != NULL) 1104: { 1105: if (((*((struct_socket *) 1106: (*((struct_liste_chainee *) element_courant)) 1107: .donnee)).socket == (*((struct_socket *) 1108: (*((struct_liste_chainee *) element_candidat)) 1109: .donnee)).socket) && 1110: ((*((struct_socket *) 1111: (*((struct_liste_chainee *) element_courant)) 1112: .donnee)).pid == (*((struct_socket *) 1113: (*((struct_liste_chainee *) element_candidat)) 1114: .donnee)).pid) && (pthread_equal( 1115: (*((struct_socket *) 1116: (*((struct_liste_chainee *) element_courant)) 1117: .donnee)).tid, (*((struct_socket *) 1118: (*((struct_liste_chainee *) element_candidat)) 1119: .donnee)).tid) != 0)) 1120: { 1121: break; 1122: } 1123: 1124: element_candidat = (*((struct_liste_chainee *) 1125: element_candidat)).suivant; 1126: } 1127: 1128: if (element_candidat == NULL) 1129: { 1130: if ((*((struct_socket *) (*((struct_liste_chainee *) 1131: element_courant)).donnee)).socket_connectee 1132: == d_vrai) 1133: { 1134: shutdown((*((struct_socket *) 1135: (*((struct_liste_chainee *) element_courant)) 1136: .donnee)).socket, SHUT_RDWR); 1137: } 1138: 1139: close((*((struct_socket *) 1140: (*((struct_liste_chainee *) element_courant)) 1141: .donnee)).socket); 1142: } 1143: 1144: pthread_mutex_trylock(&((*(*((struct_liste_chainee *) 1145: element_courant)).donnee).mutex)); 1146: pthread_mutex_unlock(&((*(*((struct_liste_chainee *) 1147: element_courant)).donnee).mutex)); 1148: 1149: liberation(s_etat_processus, 1150: (*((struct_liste_chainee *) 1151: element_courant)).donnee); 1152: free(element_courant); 1153: 1154: element_courant = element_suivant; 1155: } 1156: 1157: /* 1158: ================================================================================ 1159: À noter : on ne ferme pas la connexion car la conséquence immédiate est 1160: une destruction de l'objet pour le processus père. 1161: ================================================================================ 1162: 1163: element_courant = (*s_etat_processus).s_connecteurs_sql; 1164: while(element_courant != NULL) 1165: { 1166: element_suivant = (*((struct_liste_chainee *) 1167: element_courant)).suivant; 1168: 1169: element_candidat = (*candidat).s_connecteurs_sql; 1170: while(element_candidat != NULL) 1171: { 1172: if ((( 1173: #ifdef MYSQL_SUPPORT 1174: ((*((struct_connecteur_sql *) 1175: (*((struct_liste_chainee *) element_courant)) 1176: .donnee)).descripteur.mysql == 1177: (*((struct_connecteur_sql *) 1178: (*((struct_liste_chainee *) element_candidat)) 1179: .donnee)).descripteur.mysql) 1180: && 1181: (strcmp((*((struct_connecteur_sql *) 1182: (*((struct_liste_chainee *) element_courant)) 1183: .donnee)).type, "MYSQL") == 0) 1184: && 1185: (strcmp((*((struct_connecteur_sql *) 1186: (*((struct_liste_chainee *) element_candidat)) 1187: .donnee)).type, "MYSQL") == 0) 1188: #else 1189: 0 1190: #endif 1191: ) || ( 1192: #ifdef POSTGRESQL_SUPPORT 1193: ((*((struct_connecteur_sql *) 1194: (*((struct_liste_chainee *) element_courant)) 1195: .donnee)).descripteur.postgresql == 1196: (*((struct_connecteur_sql *) 1197: (*((struct_liste_chainee *) element_candidat)) 1198: .donnee)).descripteur.postgresql) 1199: && 1200: (strcmp((*((struct_connecteur_sql *) 1201: (*((struct_liste_chainee *) element_courant)) 1202: .donnee)).type, "POSTGRESQL") == 0) 1203: && 1204: (strcmp((*((struct_connecteur_sql *) 1205: (*((struct_liste_chainee *) element_candidat)) 1206: .donnee)).type, "POSTGRESQL") == 0) 1207: #else 1208: 0 1209: #endif 1210: )) && 1211: ((*((struct_connecteur_sql *) 1212: (*((struct_liste_chainee *) element_courant)) 1213: .donnee)).pid == (*((struct_connecteur_sql *) 1214: (*((struct_liste_chainee *) element_candidat)) 1215: .donnee)).pid) && (pthread_equal( 1216: (*((struct_connecteur_sql *) 1217: (*((struct_liste_chainee *) element_courant)) 1218: .donnee)).tid, (*((struct_connecteur_sql *) 1219: (*((struct_liste_chainee *) element_candidat)) 1220: .donnee)).tid) != 0)) 1221: { 1222: break; 1223: } 1224: 1225: element_candidat = (*((struct_liste_chainee *) 1226: element_candidat)).suivant; 1227: } 1228: 1229: if (element_candidat == NULL) 1230: { 1231: sqlclose((*((struct_liste_chainee *) element_courant)) 1232: .donnee); 1233: } 1234: 1235: pthread_mutex_trylock(&((*(*((struct_liste_chainee *) 1236: element_courant)).donnee).mutex)); 1237: pthread_mutex_unlock(&((*(*((struct_liste_chainee *) 1238: element_courant)).donnee).mutex)); 1239: 1240: liberation(s_etat_processus, (*((struct_liste_chainee *) 1241: element_courant)).donnee); 1242: free(element_courant); 1243: 1244: element_courant = element_suivant; 1245: } 1246: */ 1247: 1248: (*s_etat_processus).s_connecteurs_sql = NULL; 1249: 1250: element_courant = (*s_etat_processus).s_marques; 1251: while(element_courant != NULL) 1252: { 1253: free((*((struct_marque *) element_courant)).label); 1254: free((*((struct_marque *) element_courant)).position); 1255: element_suivant = (*((struct_marque *) element_courant)) 1256: .suivant; 1257: free(element_courant); 1258: element_courant = element_suivant; 1259: } 1260: 1261: liberation_allocateur(s_etat_processus); 1262: 1263: # ifndef SEMAPHORES_NOMMES 1264: sem_post(&((*s_etat_processus).semaphore_fork)); 1265: sem_destroy(&((*s_etat_processus).semaphore_fork)); 1266: # else 1267: sem_post((*s_etat_processus).semaphore_fork); 1268: sem_close((*s_etat_processus).semaphore_fork); 1269: # endif 1270: 1271: liberation_contexte_cas(s_etat_processus); 1272: free(s_etat_processus); 1273: 1274: s_etat_processus = candidat; 1275: } 1276: 1277: l_element_suivant = (*l_element_courant).suivant; 1278: 1279: free((struct_thread *) (*l_element_courant).donnee); 1280: free((struct_liste_chainee *) l_element_courant); 1281: 1282: l_element_courant = l_element_suivant; 1283: } 1284: 1285: liste_threads = NULL; 1286: 1287: l_element_courant = liste_threads_surveillance; 1288: 1289: while(l_element_courant != NULL) 1290: { 1291: s_argument_thread = (struct_descripteur_thread *) 1292: (*l_element_courant).donnee; 1293: 1294: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references)) 1295: != 0) 1296: { 1297: (*s_etat_processus).erreur_systeme = d_es_processus; 1298: pthread_mutex_unlock(&mutex_liste_threads); 1299: return; 1300: } 1301: 1302: (*s_argument_thread).nombre_references--; 1303: 1304: BUG((*s_argument_thread).nombre_references < 0, 1305: printf("(*s_argument_thread).nombre_references = %d\n", 1306: (int) (*s_argument_thread).nombre_references)); 1307: 1308: if ((*s_argument_thread).nombre_references == 0) 1309: { 1310: close((*s_argument_thread).pipe_objets[0]); 1311: close((*s_argument_thread).pipe_acquittement[1]); 1312: close((*s_argument_thread).pipe_injections[1]); 1313: close((*s_argument_thread).pipe_nombre_injections[1]); 1314: close((*s_argument_thread).pipe_nombre_objets_attente[0]); 1315: close((*s_argument_thread).pipe_interruptions[0]); 1316: close((*s_argument_thread).pipe_nombre_interruptions_attente[0]); 1317: 1318: if (pthread_mutex_unlock(&((*s_argument_thread) 1319: .mutex_nombre_references)) != 0) 1320: { 1321: (*s_etat_processus).erreur_systeme = d_es_processus; 1322: pthread_mutex_unlock(&mutex_liste_threads); 1323: return; 1324: } 1325: 1326: pthread_mutex_destroy(&((*s_argument_thread).mutex)); 1327: pthread_mutex_destroy(&((*s_argument_thread) 1328: .mutex_nombre_references)); 1329: 1330: if ((*s_argument_thread).processus_detache == d_faux) 1331: { 1332: if ((*s_argument_thread).destruction_objet == d_vrai) 1333: { 1334: liberation(s_etat_processus, (*s_argument_thread).argument); 1335: } 1336: } 1337: 1338: free(s_argument_thread); 1339: } 1340: else 1341: { 1342: if (pthread_mutex_unlock(&((*s_argument_thread) 1343: .mutex_nombre_references)) != 0) 1344: { 1345: (*s_etat_processus).erreur_systeme = d_es_processus; 1346: pthread_mutex_unlock(&mutex_liste_threads); 1347: return; 1348: } 1349: } 1350: 1351: l_element_suivant = (*l_element_courant).suivant; 1352: free((struct_liste_chainee *) l_element_courant); 1353: l_element_courant = l_element_suivant; 1354: } 1355: 1356: liste_threads_surveillance = NULL; 1357: 1358: if (pthread_mutex_unlock(&mutex_liste_threads) != 0) 1359: { 1360: (*s_etat_processus).erreur_systeme = d_es_processus; 1361: return; 1362: } 1363: 1364: return; 1365: } 1366: 1367: static struct_processus * 1368: recherche_thread(pid_t pid, pthread_t tid) 1369: { 1370: volatile struct_liste_chainee_volatile *l_element_courant; 1371: 1372: struct_processus *s_etat_processus; 1373: 1374: l_element_courant = liste_threads; 1375: 1376: while(l_element_courant != NULL) 1377: { 1378: if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee)) 1379: .tid, tid) != 0) && ((*((struct_thread *) 1380: (*l_element_courant).donnee)).pid == pid)) 1381: { 1382: break; 1383: } 1384: 1385: l_element_courant = (*l_element_courant).suivant; 1386: } 1387: 1388: if (l_element_courant == NULL) 1389: { 1390: /* 1391: * Le processus n'existe plus. On ne distribue aucun signal. 1392: */ 1393: 1394: return(NULL); 1395: } 1396: 1397: s_etat_processus = (*((struct_thread *) 1398: (*l_element_courant).donnee)).s_etat_processus; 1399: 1400: return(s_etat_processus); 1401: } 1402: 1403: static struct_processus * 1404: recherche_thread_principal(pid_t pid) 1405: { 1406: volatile struct_liste_chainee_volatile *l_element_courant; 1407: 1408: l_element_courant = liste_threads; 1409: 1410: while(l_element_courant != NULL) 1411: { 1412: if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal 1413: == d_vrai) && ((*((struct_thread *) 1414: (*l_element_courant).donnee)).pid == pid)) 1415: { 1416: break; 1417: } 1418: 1419: l_element_courant = (*l_element_courant).suivant; 1420: } 1421: 1422: if (l_element_courant == NULL) 1423: { 1424: /* 1425: * Le processus n'existe plus. On ne distribue aucun signal. 1426: */ 1427: 1428: return(NULL); 1429: } 1430: 1431: return((*((struct_thread *) (*l_element_courant).donnee)) 1432: .s_etat_processus); 1433: } 1434: 1435: 1436: /* 1437: ================================================================================ 1438: Procédures de gestion des signaux d'interruption 1439: ================================================================================ 1440: Entrée : variable globale 1441: -------------------------------------------------------------------------------- 1442: Sortie : variable globale modifiée 1443: -------------------------------------------------------------------------------- 1444: Effets de bord : néant 1445: ================================================================================ 1446: */ 1447: 1448: // Les routines suivantes sont uniquement appelées depuis les gestionnaires 1449: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où 1450: // les sémaphores sont déjà bloqués par un gestionnaire de signal. 1451: 1452: static inline void 1453: verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus) 1454: { 1455: int semaphore; 1456: 1457: # ifndef SEMAPHORES_NOMMES 1458: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) 1459: # else 1460: if (sem_post((*s_etat_processus).semaphore_fork) != 0) 1461: # endif 1462: { 1463: BUG(1, uprintf("Lock error !\n")); 1464: return; 1465: } 1466: 1467: // Il faut respecteur l'atomicité des deux opérations suivantes ! 1468: 1469: if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) != 0) 1470: { 1471: # ifndef SEMAPHORES_NOMMES 1472: sem_wait(&((*s_etat_processus).semaphore_fork)); 1473: # else 1474: sem_wait((*s_etat_processus).semaphore_fork); 1475: # endif 1476: BUG(1, uprintf("Unlock error !\n")); 1477: return; 1478: } 1479: 1480: # ifndef SEMAPHORES_NOMMES 1481: if (sem_post(&semaphore_gestionnaires_signaux) == -1) 1482: # else 1483: if (sem_post(semaphore_gestionnaires_signaux) == -1) 1484: # endif 1485: { 1486: # ifndef SEMAPHORES_NOMMES 1487: sem_wait(&((*s_etat_processus).semaphore_fork)); 1488: # else 1489: sem_wait((*s_etat_processus).semaphore_fork); 1490: # endif 1491: BUG(1, uprintf("Lock error !\n")); 1492: return; 1493: } 1494: 1495: # ifndef SEMAPHORES_NOMMES 1496: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0) 1497: # else 1498: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0) 1499: # endif 1500: { 1501: # ifndef SEMAPHORES_NOMMES 1502: sem_wait(&((*s_etat_processus).semaphore_fork)); 1503: # else 1504: sem_wait((*s_etat_processus).semaphore_fork); 1505: # endif 1506: BUG(1, uprintf("Lock error !\n")); 1507: return; 1508: } 1509: 1510: if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0) 1511: { 1512: # ifndef SEMAPHORES_NOMMES 1513: sem_wait(&((*s_etat_processus).semaphore_fork)); 1514: # else 1515: sem_wait((*s_etat_processus).semaphore_fork); 1516: # endif 1517: BUG(1, uprintf("Unlock error !\n")); 1518: return; 1519: } 1520: 1521: if (semaphore == 1) 1522: { 1523: // Le semaphore ne peut être pris par le thread qui a appelé 1524: // le gestionnaire de signal car le signal est bloqué par ce thread 1525: // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que 1526: // par un thread concurrent. On essaye donc de le bloquer jusqu'à 1527: // ce que ce soit possible. 1528: 1529: if (pthread_mutex_lock(&mutex_liste_threads) != 0) 1530: { 1531: # ifndef SEMAPHORES_NOMMES 1532: sem_wait(&((*s_etat_processus).semaphore_fork)); 1533: # else 1534: sem_wait((*s_etat_processus).semaphore_fork); 1535: # endif 1536: BUG(1, uprintf("Lock error !\n")); 1537: return; 1538: } 1539: } 1540: 1541: return; 1542: } 1543: 1544: static inline void 1545: deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus) 1546: { 1547: int semaphore; 1548: 1549: // Il faut respecteur l'atomicité des deux opérations suivantes ! 1550: 1551: if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) == -1) 1552: { 1553: # ifndef SEMAPHORES_NOMMES 1554: sem_wait(&((*s_etat_processus).semaphore_fork)); 1555: # else 1556: sem_wait((*s_etat_processus).semaphore_fork); 1557: # endif 1558: BUG(1, uprintf("Unlock error !\n")); 1559: return; 1560: } 1561: 1562: # ifndef SEMAPHORES_NOMMES 1563: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0) 1564: # else 1565: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0) 1566: # endif 1567: { 1568: # ifndef SEMAPHORES_NOMMES 1569: sem_wait(&((*s_etat_processus).semaphore_fork)); 1570: # else 1571: sem_wait((*s_etat_processus).semaphore_fork); 1572: # endif 1573: BUG(1, uprintf("Unlock error !\n")); 1574: return; 1575: } 1576: 1577: # ifndef SEMAPHORES_NOMMES 1578: while(sem_wait(&semaphore_gestionnaires_signaux) == -1) 1579: # else 1580: while(sem_wait(semaphore_gestionnaires_signaux) == -1) 1581: # endif 1582: { 1583: if (errno != EINTR) 1584: { 1585: # ifndef SEMAPHORES_NOMMES 1586: sem_wait(&((*s_etat_processus).semaphore_fork)); 1587: # else 1588: sem_wait((*s_etat_processus).semaphore_fork); 1589: # endif 1590: BUG(1, uprintf("Unlock error !\n")); 1591: return; 1592: } 1593: } 1594: 1595: if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0) 1596: { 1597: # ifndef SEMAPHORES_NOMMES 1598: sem_wait(&((*s_etat_processus).semaphore_fork)); 1599: # else 1600: sem_wait((*s_etat_processus).semaphore_fork); 1601: # endif 1602: BUG(1, uprintf("Unlock error !\n")); 1603: return; 1604: } 1605: 1606: # ifndef SEMAPHORES_NOMMES 1607: while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0) 1608: # else 1609: while(sem_wait((*s_etat_processus).semaphore_fork) != 0) 1610: # endif 1611: { 1612: if (errno != EINTR) 1613: { 1614: BUG(1, uprintf("Unlock error !\n")); 1615: return; 1616: } 1617: } 1618: 1619: if (semaphore == 1) 1620: { 1621: if (pthread_mutex_unlock(&mutex_liste_threads) != 0) 1622: { 1623: BUG(1, uprintf("Unlock error !\n")); 1624: return; 1625: } 1626: } 1627: 1628: return; 1629: } 1630: 1631: /* 1632: ================================================================================ 1633: Fonctions de gestion des signaux dans les threads. 1634: 1635: Lorsqu'un processus reçoit un signal, il appelle le gestionnaire de signal 1636: associé qui ne fait qu'envoyer au travers de write() le signal 1637: reçus dans un pipe. Un second thread est bloqué sur ce pipe et 1638: effectue le traitement adéquat pour le signal donné. 1639: ================================================================================ 1640: */ 1641: 1642: #define test_signal(signal) \ 1643: if (signal_test == SIGTEST) { signal_test = signal; return; } 1644: 1645: static int pipe_signaux; 1646: 1647: logical1 1648: lancement_thread_signaux(struct_processus *s_etat_processus) 1649: { 1650: pthread_attr_t attributs; 1651: 1652: void *argument; 1653: 1654: if (pipe((*s_etat_processus).pipe_signaux) != 0) 1655: { 1656: (*s_etat_processus).erreur_systeme = d_es_processus; 1657: return(d_erreur); 1658: } 1659: 1660: pipe_signaux = (*s_etat_processus).pipe_signaux[1]; 1661: 1662: if (pthread_attr_init(&attributs) != 0) 1663: { 1664: (*s_etat_processus).erreur_systeme = d_es_processus; 1665: return(d_erreur); 1666: } 1667: 1668: if (pthread_attr_setdetachstate(&attributs, PTHREAD_CREATE_JOINABLE) != 0) 1669: { 1670: (*s_etat_processus).erreur_systeme = d_es_processus; 1671: return(d_erreur); 1672: } 1673: 1674: argument = (*s_etat_processus).pipe_signaux; 1675: 1676: if (pthread_create(&((*s_etat_processus).thread_signaux), &attributs, 1677: thread_signaux, argument) != 0) 1678: { 1679: (*s_etat_processus).erreur_systeme = d_es_processus; 1680: return(d_erreur); 1681: } 1682: 1683: return(d_absence_erreur); 1684: } 1685: 1686: logical1 1687: arret_thread_signaux(struct_processus *s_etat_processus) 1688: { 1689: unsigned char signal; 1690: ssize_t n; 1691: 1692: signal = (unsigned char ) (rpl_sigmax & 0xFF); 1693: 1694: do 1695: { 1696: n = write((*s_etat_processus).pipe_signaux[1], &signal, sizeof(signal)); 1697: 1698: if (n < 0) 1699: { 1700: return(d_erreur); 1701: } 1702: } while(n != 1); 1703: 1704: pthread_join((*s_etat_processus).thread_signaux, NULL); 1705: 1706: close((*s_etat_processus).pipe_signaux[0]); 1707: close((*s_etat_processus).pipe_signaux[1]); 1708: 1709: return(d_absence_erreur); 1710: } 1711: 1712: void * 1713: thread_signaux(void *argument) 1714: { 1715: int *pipe; 1716: 1717: sigset_t masque; 1718: 1719: struct pollfd fds; 1720: 1721: unsigned char signal; 1722: 1723: pipe = (int *) argument; 1724: fds.fd = pipe[0]; 1725: fds.events = POLLIN; 1726: fds.revents = 0; 1727: 1728: sigfillset(&masque); 1729: pthread_sigmask(SIG_BLOCK, &masque, NULL); 1730: 1731: do 1732: { 1733: if (poll(&fds, 1, -1) == -1) 1734: { 1735: pthread_exit(NULL); 1736: } 1737: 1738: read(fds.fd, &signal, 1); 1739: 1740: if (signal != (0xFF & rpl_sigmax)) 1741: { 1742: uprintf("envoi signal %d vers %d\n", signal, getpid()); 1743: envoi_signal_processus(getpid(), signal); 1744: // Un signal SIGALRM est envoyé par le thread de surveillance 1745: // des signaux jusqu'à ce que les signaux soient tous traités. 1746: } 1747: } while(signal != (0xFF & rpl_sigmax)); 1748: 1749: pthread_exit(NULL); 1750: } 1751: 1752: // Récupération des signaux 1753: // - SIGINT (arrêt au clavier) 1754: // - SIGTERM (signal d'arrêt en provenance du système) 1755: 1756: void 1757: interruption1(int signal) 1758: { 1759: unsigned char signal_tronque; 1760: 1761: test_signal(signal); 1762: 1763: switch(signal) 1764: { 1765: case SIGINT: 1766: signal_tronque = (unsigned char) (rpl_sigint & 0xFF); 1767: write(pipe_signaux, &signal_tronque, sizeof(signal_tronque)); 1768: break; 1769: 1770: case SIGTERM: 1771: signal_tronque = (unsigned char) (rpl_sigterm & 0xFF); 1772: write(pipe_signaux, &signal_tronque, sizeof(signal_tronque)); 1773: break; 1774: 1775: case SIGUSR1: 1776: signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF); 1777: write(pipe_signaux, &signal_tronque, sizeof(signal_tronque)); 1778: break; 1779: 1780: default: 1781: // SIGALRM 1782: break; 1783: } 1784: 1785: return; 1786: } 1787: 1788: // Récupération des signaux 1789: // - SIGFSTP 1790: // 1791: // ATTENTION : 1792: // Le signal SIGFSTP provient de la mort du processus de contrôle. 1793: // Sous certains systèmes (Linux...), la mort du terminal de contrôle 1794: // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres 1795: // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo 1796: // non initialisée (pointeur NULL) issue de TERMIO. 1797: 1798: void 1799: interruption2(int signal) 1800: { 1801: unsigned char signal_tronque; 1802: 1803: test_signal(signal); 1804: 1805: signal_tronque = (unsigned char) (rpl_sigtstp & 0xFF); 1806: write(pipe_signaux, &signal_tronque, sizeof(signal_tronque)); 1807: return; 1808: } 1809: 1810: void 1811: interruption3(int signal) 1812: { 1813: // Si on passe par ici, c'est qu'il est impossible de récupérer 1814: // l'erreur d'accès à la mémoire. On sort donc du programme quitte à 1815: // ce qu'il reste des processus orphelins. 1816: 1817: unsigned char message_1[] = "+++System : Uncaught access violation\n" 1818: "+++System : Aborting !\n"; 1819: unsigned char message_2[] = "+++System : Stack overflow\n" 1820: "+++System : Aborting !\n"; 1821: 1822: test_signal(signal); 1823: 1824: if (pid_processus_pere == getpid()) 1825: { 1826: kill(pid_processus_pere, SIGUSR1); 1827: } 1828: 1829: if (signal != SIGUSR2) 1830: { 1831: write(STDERR_FILENO, message_1, strlen(message_1)); 1832: } 1833: else 1834: { 1835: write(STDERR_FILENO, message_2, strlen(message_2)); 1836: } 1837: 1838: _exit(EXIT_FAILURE); 1839: } 1840: 1841: // Récupération des signaux 1842: // - SIGHUP 1843: 1844: void 1845: interruption4(int signal) 1846: { 1847: unsigned char signal_tronque; 1848: 1849: test_signal(signal); 1850: 1851: signal_tronque = (unsigned char) (rpl_sighup & 0xFF); 1852: write(pipe_signaux, &signal_tronque, sizeof(signal_tronque)); 1853: return; 1854: } 1855: 1856: // Récupération des signaux 1857: // - SIGPIPE 1858: 1859: void 1860: interruption5(int signal) 1861: { 1862: unsigned char message[] = "+++System : SIGPIPE\n" 1863: "+++System : Aborting !\n"; 1864: unsigned char signal_tronque; 1865: 1866: test_signal(signal); 1867: 1868: if (pid_processus_pere == getpid()) 1869: { 1870: signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF); 1871: write(pipe_signaux, &signal_tronque, sizeof(signal_tronque)); 1872: } 1873: 1874: write(STDERR_FILENO, message, strlen(message)); 1875: return; 1876: } 1877: 1878: inline static void 1879: signal_alrm(struct_processus *s_etat_processus, pid_t pid) 1880: { 1881: struct_processus *s_thread_principal; 1882: 1883: verrouillage_gestionnaire_signaux(s_etat_processus); 1884: 1885: if (pid == getpid()) 1886: { 1887: // Si pid est égal à getpid(), le signal à traiter est issu 1888: // du même processus que celui qui va le traiter, mais d'un thread 1889: // différent. 1890: 1891: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0) 1892: { 1893: printf("[%d] RPL/SIGALRM (thread %llu)\n", (int) getpid(), 1894: (unsigned long long) pthread_self()); 1895: fflush(stdout); 1896: } 1897: 1898: if ((*s_etat_processus).pid_processus_pere != getpid()) 1899: { 1900: // On n'est pas dans le processus père, on remonte le signal. 1901: envoi_signal_processus((*s_etat_processus).pid_processus_pere, 1902: rpl_sigalrm); 1903: } 1904: else 1905: { 1906: // On est dans le processus père, on effectue un arrêt d'urgence. 1907: (*s_etat_processus).var_volatile_alarme = -1; 1908: (*s_etat_processus).var_volatile_requete_arret = -1; 1909: } 1910: } 1911: else 1912: { 1913: // Le signal est issu d'un processus différent. On recherche le 1914: // thread principal pour remonter le signal. 1915: 1916: if ((s_thread_principal = recherche_thread_principal(getpid())) 1917: != NULL) 1918: { 1919: envoi_signal_contexte(s_thread_principal, rpl_sigalrm); 1920: } 1921: } 1922: 1923: deverrouillage_gestionnaire_signaux(s_etat_processus); 1924: return; 1925: } 1926: 1927: inline static void 1928: signal_term(struct_processus *s_etat_processus, pid_t pid) 1929: { 1930: struct_processus *s_thread_principal; 1931: pthread_mutex_t exclusion = PTHREAD_MUTEX_INITIALIZER; 1932: 1933: verrouillage_gestionnaire_signaux(s_etat_processus); 1934: 1935: if (pid == getpid()) 1936: { 1937: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0) 1938: { 1939: printf("[%d] RPL/SIGTERM (thread %llu)\n", (int) getpid(), 1940: (unsigned long long) pthread_self()); 1941: fflush(stdout); 1942: } 1943: 1944: if ((*s_etat_processus).pid_processus_pere != getpid()) 1945: { 1946: envoi_signal_processus((*s_etat_processus).pid_processus_pere, 1947: rpl_sigterm); 1948: } 1949: else 1950: { 1951: (*s_etat_processus).var_volatile_traitement_sigint = -1; 1952: 1953: pthread_mutex_lock(&exclusion); 1954: 1955: if ((*s_etat_processus).var_volatile_requete_arret == -1) 1956: { 1957: deverrouillage_gestionnaire_signaux(s_etat_processus); 1958: pthread_mutex_unlock(&exclusion); 1959: return; 1960: } 1961: 1962: (*s_etat_processus).var_volatile_requete_arret = -1; 1963: (*s_etat_processus).var_volatile_alarme = -1; 1964: 1965: pthread_mutex_unlock(&exclusion); 1966: } 1967: } 1968: else 1969: { 1970: if ((s_thread_principal = recherche_thread_principal(getpid())) 1971: != NULL) 1972: { 1973: envoi_signal_contexte(s_thread_principal, rpl_sigterm); 1974: } 1975: } 1976: 1977: deverrouillage_gestionnaire_signaux(s_etat_processus); 1978: return; 1979: } 1980: 1981: inline static void 1982: signal_int(struct_processus *s_etat_processus, pid_t pid) 1983: { 1984: struct_processus *s_thread_principal; 1985: volatile sig_atomic_t exclusion = 0; 1986: 1987: verrouillage_gestionnaire_signaux(s_etat_processus); 1988: 1989: if (pid == getpid()) 1990: { 1991: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0) 1992: { 1993: printf("[%d] RPL/SIGINT (thread %llu)\n", (int) getpid(), 1994: (unsigned long long) pthread_self()); 1995: fflush(stdout); 1996: } 1997: 1998: if ((*s_etat_processus).pid_processus_pere != getpid()) 1999: { 2000: envoi_signal_processus((*s_etat_processus).pid_processus_pere, 2001: rpl_sigint); 2002: } 2003: else 2004: { 2005: (*s_etat_processus).var_volatile_traitement_sigint = -1; 2006: 2007: while(exclusion == 1); 2008: exclusion = 1; 2009: 2010: if ((*s_etat_processus).var_volatile_requete_arret == -1) 2011: { 2012: deverrouillage_gestionnaire_signaux(s_etat_processus); 2013: exclusion = 0; 2014: return; 2015: } 2016: 2017: if ((*s_etat_processus).langue == 'F') 2018: { 2019: printf("+++Interruption\n"); 2020: } 2021: else 2022: { 2023: printf("+++Interrupt\n"); 2024: } 2025: 2026: fflush(stdout); 2027: 2028: (*s_etat_processus).var_volatile_requete_arret = -1; 2029: (*s_etat_processus).var_volatile_alarme = -1; 2030: 2031: exclusion = 0; 2032: } 2033: } 2034: else 2035: { 2036: if ((s_thread_principal = recherche_thread_principal(getpid())) 2037: != NULL) 2038: { 2039: envoi_signal_contexte(s_thread_principal, rpl_sigint); 2040: } 2041: } 2042: 2043: deverrouillage_gestionnaire_signaux(s_etat_processus); 2044: return; 2045: } 2046: 2047: static inline void 2048: signal_tstp(struct_processus *s_etat_processus, pid_t pid) 2049: { 2050: struct_processus *s_thread_principal; 2051: 2052: verrouillage_gestionnaire_signaux(s_etat_processus); 2053: 2054: if (pid == getpid()) 2055: { 2056: /* 2057: * 0 => fonctionnement normal 2058: * -1 => requête 2059: * 1 => requête acceptée en attente de traitement 2060: */ 2061: 2062: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0) 2063: { 2064: printf("[%d] RPL/SIGTSTP (thread %llu)\n", (int) getpid(), 2065: (unsigned long long) pthread_self()); 2066: fflush(stdout); 2067: } 2068: 2069: if ((*s_etat_processus).var_volatile_processus_pere == 0) 2070: { 2071: envoi_signal_processus((*s_etat_processus).pid_processus_pere, 2072: rpl_sigtstp); 2073: } 2074: else 2075: { 2076: (*s_etat_processus).var_volatile_requete_arret2 = -1; 2077: } 2078: } 2079: else 2080: { 2081: // Envoi d'un signal au thread maître du groupe. 2082: 2083: if ((s_thread_principal = recherche_thread_principal(getpid())) 2084: != NULL) 2085: { 2086: envoi_signal_contexte(s_thread_principal, rpl_sigtstp); 2087: } 2088: } 2089: 2090: deverrouillage_gestionnaire_signaux(s_etat_processus); 2091: return; 2092: } 2093: 2094: static void 2095: sortie_interruption_depassement_pile(void *arg1, void *arg2, void *arg3) 2096: { 2097: switch((*((volatile int *) arg1))) 2098: { 2099: case 1: 2100: longjmp(contexte_ecriture, -1); 2101: break; 2102: 2103: case 2: 2104: longjmp(contexte_impression, -1); 2105: break; 2106: } 2107: 2108: return; 2109: } 2110: 2111: void 2112: interruption_depassement_pile(int urgence, stackoverflow_context_t scp) 2113: { 2114: if ((urgence == 0) && (routine_recursive != 0)) 2115: { 2116: // On peut tenter de récupérer le dépassement de pile. Si la variable 2117: // 'routine_recursive' est non nulle, on récupère l'erreur. 2118: 2119: sigsegv_leave_handler(sortie_interruption_depassement_pile, 2120: (void *) &routine_recursive, NULL, NULL); 2121: } 2122: 2123: // Ici, la panique est totale et il vaut mieux quitter l'application. 2124: interruption3(SIGUSR2); 2125: return; 2126: } 2127: 2128: int 2129: interruption_violation_access(void *adresse_fautive, int gravite) 2130: { 2131: unsigned char message[] = "+++System : Trying to catch access " 2132: "violation\n"; 2133: 2134: static int compteur_erreur = 0; 2135: 2136: if ((gravite == 0) && (routine_recursive != 0)) 2137: { 2138: // Il peut s'agir d'un dépassement de pile. 2139: 2140: sigsegv_leave_handler(sortie_interruption_depassement_pile, 2141: (void *) &routine_recursive, NULL, NULL); 2142: } 2143: 2144: // On est dans une bonne vieille violation d'accès. On essaie 2145: // de fermer au mieux l'application. 2146: 2147: compteur_erreur++; 2148: 2149: if (compteur_erreur >= 2) 2150: { 2151: // Erreurs multiples, on arrête l'application. 2152: interruption3(SIGSEGV); 2153: return(0); 2154: } 2155: 2156: write(STDERR_FILENO, message, strlen(message)); 2157: 2158: if (pid_processus_pere == getpid()) 2159: { 2160: longjmp(contexte_initial, -1); 2161: return(1); 2162: } 2163: else 2164: { 2165: longjmp(contexte_processus, -1); 2166: return(1); 2167: } 2168: 2169: // On renvoie 0 parce qu'on décline toute responsabilité quant à la 2170: // suite des événements... 2171: return(0); 2172: } 2173: 2174: // Traitement de rpl_sigstart 2175: 2176: static inline void 2177: signal_start(struct_processus *s_etat_processus, pid_t pid) 2178: { 2179: struct_processus *s_thread_principal; 2180: 2181: verrouillage_gestionnaire_signaux(s_etat_processus); 2182: 2183: if (pid == getpid()) 2184: { 2185: (*s_etat_processus).demarrage_fils = d_vrai; 2186: } 2187: else 2188: { 2189: // Envoi d'un signal au thread maître du groupe. 2190: 2191: if ((s_thread_principal = recherche_thread_principal(getpid())) 2192: != NULL) 2193: { 2194: envoi_signal_contexte(s_thread_principal, rpl_sigstart); 2195: } 2196: } 2197: 2198: deverrouillage_gestionnaire_signaux(s_etat_processus); 2199: return; 2200: } 2201: 2202: // Traitement de rpl_sigcont 2203: 2204: static inline void 2205: signal_cont(struct_processus *s_etat_processus, pid_t pid) 2206: { 2207: struct_processus *s_thread_principal; 2208: 2209: verrouillage_gestionnaire_signaux(s_etat_processus); 2210: 2211: if (pid == getpid()) 2212: { 2213: (*s_etat_processus).redemarrage_processus = d_vrai; 2214: } 2215: else 2216: { 2217: // Envoi d'un signal au thread maître du groupe. 2218: 2219: if ((s_thread_principal = recherche_thread_principal(getpid())) 2220: != NULL) 2221: { 2222: envoi_signal_contexte(s_thread_principal, rpl_sigcont); 2223: } 2224: } 2225: 2226: deverrouillage_gestionnaire_signaux(s_etat_processus); 2227: return; 2228: } 2229: 2230: // Traitement de rpl_sigstop 2231: 2232: static inline void 2233: signal_stop(struct_processus *s_etat_processus, pid_t pid) 2234: { 2235: struct_processus *s_thread_principal; 2236: 2237: verrouillage_gestionnaire_signaux(s_etat_processus); 2238: 2239: if (pid == getpid()) 2240: { 2241: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0) 2242: { 2243: printf("[%d] RPL/SIGSTOP (thread %llu)\n", (int) getpid(), 2244: (unsigned long long) pthread_self()); 2245: fflush(stdout); 2246: } 2247: 2248: /* 2249: * var_globale_traitement_retarde_stop : 2250: * 0 -> traitement immédiat 2251: * 1 -> traitement retardé (aucun signal reçu) 2252: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus) 2253: */ 2254: 2255: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0) 2256: { 2257: (*s_etat_processus).var_volatile_requete_arret = -1; 2258: } 2259: else 2260: { 2261: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1; 2262: } 2263: } 2264: else 2265: { 2266: // Envoi d'un signal au thread maître du groupe. 2267: 2268: if ((s_thread_principal = recherche_thread_principal(getpid())) 2269: != NULL) 2270: { 2271: envoi_signal_contexte(s_thread_principal, rpl_sigstop); 2272: } 2273: } 2274: 2275: deverrouillage_gestionnaire_signaux(s_etat_processus); 2276: return; 2277: } 2278: 2279: // Traitement de rpl_siginject 2280: 2281: static inline void 2282: signal_inject(struct_processus *s_etat_processus, pid_t pid) 2283: { 2284: verrouillage_gestionnaire_signaux(s_etat_processus); 2285: 2286: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) 2287: { 2288: deverrouillage_gestionnaire_signaux(s_etat_processus); 2289: return; 2290: } 2291: 2292: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0) 2293: { 2294: printf("[%d] RPL/SIGINJECT (thread %llu)\n", (int) getpid(), 2295: (unsigned long long) pthread_self()); 2296: fflush(stdout); 2297: } 2298: 2299: deverrouillage_gestionnaire_signaux(s_etat_processus); 2300: return; 2301: } 2302: 2303: 2304: static inline void 2305: signal_urg(struct_processus *s_etat_processus, pid_t pid) 2306: { 2307: struct_processus *s_thread_principal; 2308: 2309: verrouillage_gestionnaire_signaux(s_etat_processus); 2310: 2311: if (pid == getpid()) 2312: { 2313: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0) 2314: { 2315: printf("[%d] RPL/SIGURG (thread %llu)\n", (int) getpid(), 2316: (unsigned long long) pthread_self()); 2317: fflush(stdout); 2318: } 2319: 2320: (*s_etat_processus).var_volatile_alarme = -1; 2321: (*s_etat_processus).var_volatile_requete_arret = -1; 2322: } 2323: else 2324: { 2325: // Envoi d'un signal au thread maître du groupe. 2326: 2327: if ((s_thread_principal = recherche_thread_principal(getpid())) 2328: != NULL) 2329: { 2330: envoi_signal_contexte(s_thread_principal, rpl_sigurg); 2331: } 2332: } 2333: 2334: deverrouillage_gestionnaire_signaux(s_etat_processus); 2335: return; 2336: } 2337: 2338: // Traitement de rpl_sigabort 2339: 2340: static inline void 2341: signal_abort(struct_processus *s_etat_processus, pid_t pid) 2342: { 2343: struct_processus *s_thread_principal; 2344: 2345: verrouillage_gestionnaire_signaux(s_etat_processus); 2346: 2347: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) 2348: { 2349: deverrouillage_gestionnaire_signaux(s_etat_processus); 2350: return; 2351: } 2352: 2353: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0) 2354: { 2355: printf("[%d] RPL/SIGABORT (thread %llu)\n", (int) getpid(), 2356: (unsigned long long) pthread_self()); 2357: fflush(stdout); 2358: } 2359: 2360: if (pid == getpid()) 2361: { 2362: (*s_etat_processus).arret_depuis_abort = -1; 2363: 2364: /* 2365: * var_globale_traitement_retarde_stop : 2366: * 0 -> traitement immédiat 2367: * 1 -> traitement retardé (aucun signal reçu) 2368: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus) 2369: */ 2370: 2371: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0) 2372: { 2373: (*s_etat_processus).var_volatile_requete_arret = -1; 2374: } 2375: else 2376: { 2377: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1; 2378: } 2379: } 2380: else 2381: { 2382: (*s_etat_processus).arret_depuis_abort = -1; 2383: 2384: // Envoi d'un signal au thread maître du groupe. 2385: 2386: if ((s_thread_principal = recherche_thread_principal(getpid())) 2387: != NULL) 2388: { 2389: envoi_signal_contexte(s_thread_principal, rpl_sigabort); 2390: } 2391: } 2392: 2393: deverrouillage_gestionnaire_signaux(s_etat_processus); 2394: return; 2395: } 2396: 2397: 2398: static inline void 2399: signal_hup(struct_processus *s_etat_processus, pid_t pid) 2400: { 2401: file *fichier; 2402: 2403: unsigned char nom[8 + 64 + 1]; 2404: 2405: verrouillage_gestionnaire_signaux(s_etat_processus); 2406: 2407: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) 2408: { 2409: deverrouillage_gestionnaire_signaux(s_etat_processus); 2410: return; 2411: } 2412: 2413: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(), 2414: (unsigned long) pthread_self()); 2415: 2416: if ((fichier = fopen(nom, "w+")) != NULL) 2417: { 2418: fclose(fichier); 2419: 2420: freopen(nom, "w", stdout); 2421: freopen(nom, "w", stderr); 2422: } 2423: 2424: freopen("/dev/null", "r", stdin); 2425: 2426: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0) 2427: { 2428: printf("[%d] RPL/SIGHUP (thread %llu)\n", (int) getpid(), 2429: (unsigned long long) pthread_self()); 2430: fflush(stdout); 2431: } 2432: 2433: deverrouillage_gestionnaire_signaux(s_etat_processus); 2434: return; 2435: } 2436: 2437: void 2438: traitement_exceptions_gsl(const char *reason, const char *file, 2439: int line, int gsl_errno) 2440: { 2441: code_erreur_gsl = gsl_errno; 2442: envoi_signal_processus(getpid(), rpl_sigexcept); 2443: return; 2444: } 2445: 2446: static inline void 2447: signal_except(struct_processus *s_etat_processus, pid_t pid) 2448: { 2449: verrouillage_gestionnaire_signaux(s_etat_processus); 2450: 2451: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) 2452: { 2453: deverrouillage_gestionnaire_signaux(s_etat_processus); 2454: return; 2455: } 2456: 2457: (*s_etat_processus).var_volatile_exception_gsl = code_erreur_gsl; 2458: deverrouillage_gestionnaire_signaux(s_etat_processus); 2459: 2460: return; 2461: } 2462: 2463: static inline void 2464: envoi_interruptions(struct_processus *s_etat_processus, enum signaux_rpl signal, 2465: pid_t pid_source) 2466: { 2467: switch(signal) 2468: { 2469: case rpl_signull: 2470: break; 2471: 2472: case rpl_sigint: 2473: signal_int(s_etat_processus, pid_source); 2474: break; 2475: 2476: case rpl_sigterm: 2477: signal_term(s_etat_processus, pid_source); 2478: break; 2479: 2480: case rpl_sigstart: 2481: signal_start(s_etat_processus, pid_source); 2482: break; 2483: 2484: case rpl_sigcont: 2485: signal_cont(s_etat_processus, pid_source); 2486: break; 2487: 2488: case rpl_sigstop: 2489: signal_stop(s_etat_processus, pid_source); 2490: break; 2491: 2492: case rpl_sigabort: 2493: signal_abort(s_etat_processus, pid_source); 2494: break; 2495: 2496: case rpl_sigurg: 2497: signal_urg(s_etat_processus, pid_source); 2498: break; 2499: 2500: case rpl_siginject: 2501: signal_inject(s_etat_processus, pid_source); 2502: break; 2503: 2504: case rpl_sigalrm: 2505: signal_alrm(s_etat_processus, pid_source); 2506: break; 2507: 2508: case rpl_sighup: 2509: signal_hup(s_etat_processus, pid_source); 2510: break; 2511: 2512: case rpl_sigtstp: 2513: signal_tstp(s_etat_processus, pid_source); 2514: break; 2515: 2516: case rpl_sigexcept: 2517: signal_except(s_etat_processus, pid_source); 2518: break; 2519: 2520: default: 2521: if ((*s_etat_processus).langue == 'F') 2522: { 2523: printf("+++System : Signal inconnu (%d) !\n", signal); 2524: } 2525: else 2526: { 2527: printf("+++System : Spurious signal (%d) !\n", signal); 2528: } 2529: 2530: break; 2531: } 2532: 2533: return; 2534: } 2535: 2536: void 2537: scrutation_interruptions(struct_processus *s_etat_processus) 2538: { 2539: // Interruptions qui arrivent sur le processus depuis un 2540: // processus externe. 2541: 2542: // Les pointeurs de lecture pointent sur les prochains éléments 2543: // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à 2544: // écrire. 2545: 2546: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 2547: if (sem_trywait(&((*s_queue_signaux).semaphore)) == 0) 2548: # else 2549: if (sem_trywait(semaphore_queue_signaux) == 0) 2550: # endif 2551: { 2552: while((*s_queue_signaux).pointeur_lecture != 2553: (*s_queue_signaux).pointeur_ecriture) 2554: { 2555: // Il y a un signal en attente dans le segment partagé. On le 2556: // traite. 2557: 2558: envoi_interruptions(s_etat_processus, 2559: (*s_queue_signaux).queue[(*s_queue_signaux) 2560: .pointeur_lecture].signal, (*s_queue_signaux).queue 2561: [(*s_queue_signaux).pointeur_lecture].pid); 2562: (*s_queue_signaux).pointeur_lecture = 2563: ((*s_queue_signaux).pointeur_lecture + 1) 2564: % LONGUEUR_QUEUE_SIGNAUX; 2565: 2566: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 2567: while(sem_wait(&((*s_queue_signaux).signalisation)) != 0) 2568: # else 2569: while(sem_wait(semaphore_signalisation) != 0) 2570: # endif 2571: { 2572: if (errno != EINTR) 2573: { 2574: (*s_etat_processus).erreur_systeme = d_es_processus; 2575: return; 2576: } 2577: } 2578: } 2579: 2580: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 2581: sem_post(&((*s_queue_signaux).semaphore)); 2582: # else 2583: sem_post(semaphore_queue_signaux); 2584: # endif 2585: } 2586: 2587: // Interruptions qui arrivent depuis le groupe courant de threads. 2588: 2589: if (pthread_mutex_trylock(&mutex_interruptions) == 0) 2590: { 2591: while((*s_etat_processus).pointeur_signal_lecture != 2592: (*s_etat_processus).pointeur_signal_ecriture) 2593: { 2594: // Il y a un signal dans la queue du thread courant. On le traite. 2595: 2596: envoi_interruptions(s_etat_processus, 2597: (*s_etat_processus).signaux_en_queue 2598: [(*s_etat_processus).pointeur_signal_lecture], 2599: getpid()); 2600: (*s_etat_processus).pointeur_signal_lecture = 2601: ((*s_etat_processus).pointeur_signal_lecture + 1) 2602: % LONGUEUR_QUEUE_SIGNAUX; 2603: 2604: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 2605: while(sem_wait(&((*s_queue_signaux).signalisation)) != 0) 2606: # else 2607: while(sem_wait(semaphore_signalisation) != 0) 2608: # endif 2609: { 2610: if (errno != EINTR) 2611: { 2612: (*s_etat_processus).erreur_systeme = d_es_processus; 2613: return; 2614: } 2615: } 2616: } 2617: 2618: pthread_mutex_unlock(&mutex_interruptions); 2619: } 2620: 2621: return; 2622: } 2623: 2624: /* 2625: ================================================================================ 2626: Fonction renvoyant le nom du segment de mémoire partagée en fonction 2627: du pid du processus. 2628: ================================================================================ 2629: Entrée : Chemin absolue servant de racine, pid du processus 2630: -------------------------------------------------------------------------------- 2631: Sortie : NULL ou nom du segment 2632: -------------------------------------------------------------------------------- 2633: Effet de bord : Néant 2634: ================================================================================ 2635: */ 2636: 2637: static unsigned char * 2638: nom_segment(unsigned char *chemin, pid_t pid) 2639: { 2640: unsigned char *fichier; 2641: 2642: # ifdef IPCS_SYSV // !POSIX 2643: # ifndef OS2 // !OS2 2644: 2645: if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) * 2646: sizeof(unsigned char))) == NULL) 2647: { 2648: return(NULL); 2649: } 2650: 2651: sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid); 2652: # else // OS2 2653: if ((fichier = malloc((10 + 256 + 1) * sizeof(unsigned char))) 2654: == NULL) 2655: { 2656: return(NULL); 2657: } 2658: 2659: sprintf(fichier, "\\SHAREMEM\\RPL-SIGQUEUES-%d", (int) pid); 2660: # endif // OS2 2661: # else // POSIX 2662: 2663: if ((fichier = malloc((1 + 256 + 1) * 2664: sizeof(unsigned char))) == NULL) 2665: { 2666: return(NULL); 2667: } 2668: 2669: sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid); 2670: # endif 2671: 2672: return(fichier); 2673: } 2674: 2675: 2676: /* 2677: ================================================================================ 2678: Fonctions d'envoi d'un signal à un thread ou à un processus. 2679: ================================================================================ 2680: Entrée : processus et signal 2681: -------------------------------------------------------------------------------- 2682: Sortie : erreur 2683: -------------------------------------------------------------------------------- 2684: Effet de bord : Néant 2685: ================================================================================ 2686: */ 2687: 2688: int 2689: envoi_signal_processus(pid_t pid, enum signaux_rpl signal) 2690: { 2691: # ifndef OS2 2692: int segment; 2693: # endif 2694: 2695: # ifndef IPCS_SYSV 2696: # ifdef SEMAPHORES_NOMMES 2697: sem_t *semaphore; 2698: sem_t *signalisation; 2699: # endif 2700: # else 2701: # ifndef OS2 2702: int desc; 2703: key_t clef; 2704: # endif 2705: # endif 2706: 2707: struct_queue_signaux *queue; 2708: 2709: unsigned char *nom; 2710: 2711: // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en 2712: // mémoire puis d'y inscrire le signal à traiter. 2713: 2714: if (pid == getpid()) 2715: { 2716: // Le signal est envoyé au même processus. 2717: 2718: if (s_queue_signaux == NULL) 2719: { 2720: return(1); 2721: } 2722: 2723: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 2724: while(sem_wait(&((*s_queue_signaux).semaphore)) != 0) 2725: # else 2726: while(sem_wait(semaphore_queue_signaux) != 0) 2727: # endif 2728: { 2729: if (errno != EINTR) 2730: { 2731: return(1); 2732: } 2733: } 2734: 2735: (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture] 2736: .pid = pid; 2737: (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture] 2738: .signal = signal; 2739: 2740: (*s_queue_signaux).pointeur_ecriture = 2741: ((*s_queue_signaux).pointeur_ecriture + 1) 2742: % LONGUEUR_QUEUE_SIGNAUX; 2743: 2744: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 2745: if (sem_post(&((*s_queue_signaux).semaphore)) != 0) 2746: # else 2747: if (sem_post(semaphore_queue_signaux) != 0) 2748: # endif 2749: { 2750: return(1); 2751: } 2752: 2753: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 2754: if (sem_post(&((*s_queue_signaux).signalisation)) != 0) 2755: # else 2756: if (sem_post(semaphore_signalisation) != 0) 2757: # endif 2758: { 2759: return(1); 2760: } 2761: } 2762: else 2763: { 2764: // Le signal est envoyé depuis un processus distinct. 2765: 2766: # ifdef IPCS_SYSV 2767: if ((nom = nom_segment(racine_segment, pid)) == NULL) 2768: { 2769: return(1); 2770: } 2771: 2772: # ifndef OS2 // SysV 2773: if ((desc = open(nom, O_RDWR)) == -1) 2774: { 2775: free(nom); 2776: return(1); 2777: } 2778: 2779: close(desc); 2780: 2781: if ((clef = ftok(nom, 1)) == -1) 2782: { 2783: free(nom); 2784: return(1); 2785: } 2786: 2787: free(nom); 2788: 2789: if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0)) 2790: == -1) 2791: { 2792: return(1); 2793: } 2794: 2795: queue = shmat(segment, NULL, 0); 2796: # else // OS/2 2797: if (DosGetNamedSharedMem((PVOID) &queue, nom, 2798: PAG_WRITE | PAG_READ) != 0) 2799: { 2800: free(nom); 2801: return(1); 2802: } 2803: 2804: free(nom); 2805: # endif 2806: # else // POSIX 2807: if ((nom = nom_segment(racine_segment, pid)) == NULL) 2808: { 2809: return(1); 2810: } 2811: 2812: if ((segment = shm_open(nom, O_RDWR, 0)) == -1) 2813: { 2814: free(nom); 2815: return(1); 2816: } 2817: 2818: free(nom); 2819: 2820: if ((queue = mmap(NULL, sizeof(struct_queue_signaux), 2821: PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0)) == 2822: MAP_FAILED) 2823: { 2824: close(segment); 2825: return(1); 2826: } 2827: # endif 2828: 2829: // À ce moment, le segment de mémoire partagée est projeté 2830: // dans l'espace du processus. 2831: 2832: # ifndef IPCS_SYSV // POSIX 2833: # ifndef SEMAPHORES_NOMMES 2834: while(sem_wait(&((*queue).semaphore)) != 0) 2835: { 2836: if (errno != EINTR) 2837: { 2838: return(1); 2839: } 2840: } 2841: # else 2842: if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED) 2843: { 2844: return(1); 2845: } 2846: 2847: if ((signalisation = sem_open2(pid, SEM_SIGNALISATION)) 2848: == SEM_FAILED) 2849: { 2850: return(1); 2851: } 2852: 2853: while(sem_wait(semaphore) != 0) 2854: { 2855: if (errno != EINTR) 2856: { 2857: sem_close(semaphore); 2858: sem_close(signalisation); 2859: return(1); 2860: } 2861: } 2862: # endif 2863: # else // IPCS_SYSV 2864: while(sem_wait(&((*queue).semaphore)) != 0) 2865: { 2866: if (errno != EINTR) 2867: { 2868: return(1); 2869: } 2870: } 2871: # endif 2872: 2873: (*queue).queue[(*queue).pointeur_ecriture].pid = getpid(); 2874: (*queue).queue[(*queue).pointeur_ecriture].signal = signal; 2875: 2876: (*queue).pointeur_ecriture = ((*queue).pointeur_ecriture + 1) 2877: % LONGUEUR_QUEUE_SIGNAUX; 2878: 2879: # ifndef IPCS_SYSV // POSIX 2880: # ifndef SEMAPHORES_NOMMES 2881: if (sem_post(&((*queue).semaphore)) != 0) 2882: { 2883: return(1); 2884: } 2885: 2886: if (sem_post(&((*queue).signalisation)) != 0) 2887: { 2888: return(1); 2889: } 2890: # else 2891: if (sem_post(semaphore) != 0) 2892: { 2893: sem_close(semaphore); 2894: sem_close(signalisation); 2895: return(1); 2896: } 2897: 2898: if (sem_close(semaphore) != 0) 2899: { 2900: return(1); 2901: } 2902: 2903: if (sem_post(signalisation) != 0) 2904: { 2905: sem_close(signalisation); 2906: return(1); 2907: } 2908: 2909: if (sem_close(signalisation) != 0) 2910: { 2911: return(1); 2912: } 2913: 2914: # endif 2915: 2916: if (munmap(queue, sizeof(struct_queue_signaux)) != 0) 2917: { 2918: close(segment); 2919: return(1); 2920: } 2921: # else // IPCS_SYSV 2922: if (sem_post(&((*queue).semaphore)) != 0) 2923: { 2924: return(1); 2925: } 2926: 2927: if (sem_post(&((*queue).signalisation)) != 0) 2928: { 2929: return(1); 2930: } 2931: 2932: # ifndef OS2 // SysV 2933: if (shmdt(queue) != 0) 2934: { 2935: return(1); 2936: } 2937: # else // OS/2 2938: // Pendant de DosGetNamedSHaredMem() 2939: # endif 2940: # endif 2941: } 2942: 2943: return(0); 2944: } 2945: 2946: int 2947: envoi_signal_thread(pthread_t tid, enum signaux_rpl signal) 2948: { 2949: // Un signal est envoyé d'un thread à un autre thread du même processus. 2950: 2951: volatile struct_liste_chainee_volatile *l_element_courant; 2952: 2953: struct_processus *s_etat_processus; 2954: 2955: if (pthread_mutex_lock(&mutex_liste_threads) != 0) 2956: { 2957: return(1); 2958: } 2959: 2960: l_element_courant = liste_threads; 2961: 2962: while(l_element_courant != NULL) 2963: { 2964: if (((*((struct_thread *) (*l_element_courant).donnee)).pid 2965: == getpid()) && (pthread_equal((*((struct_thread *) 2966: (*l_element_courant).donnee)).tid, tid) != 0)) 2967: { 2968: break; 2969: } 2970: 2971: l_element_courant = (*l_element_courant).suivant; 2972: } 2973: 2974: if (l_element_courant == NULL) 2975: { 2976: pthread_mutex_unlock(&mutex_liste_threads); 2977: return(1); 2978: } 2979: 2980: if (pthread_mutex_lock(&mutex_interruptions) != 0) 2981: { 2982: pthread_mutex_unlock(&mutex_liste_threads); 2983: return(1); 2984: } 2985: 2986: s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee)) 2987: .s_etat_processus; 2988: 2989: (*s_etat_processus).signaux_en_queue 2990: [(*s_etat_processus).pointeur_signal_ecriture] = signal; 2991: (*s_etat_processus).pointeur_signal_ecriture = 2992: ((*s_etat_processus).pointeur_signal_ecriture + 1) 2993: % LONGUEUR_QUEUE_SIGNAUX; 2994: 2995: if (pthread_mutex_unlock(&mutex_interruptions) != 0) 2996: { 2997: pthread_mutex_unlock(&mutex_liste_threads); 2998: return(1); 2999: } 3000: 3001: if (pthread_mutex_unlock(&mutex_liste_threads) != 0) 3002: { 3003: return(1); 3004: } 3005: 3006: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 3007: if (sem_post(&((*s_queue_signaux).signalisation)) != 0) 3008: { 3009: return(1); 3010: } 3011: # else 3012: if (sem_post(semaphore_signalisation) != 0) 3013: { 3014: return(1); 3015: } 3016: # endif 3017: 3018: return(0); 3019: } 3020: 3021: int 3022: envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler, 3023: enum signaux_rpl signal) 3024: { 3025: pthread_mutex_lock(&mutex_interruptions); 3026: (*s_etat_processus_a_signaler).signaux_en_queue 3027: [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] = 3028: signal; 3029: (*s_etat_processus_a_signaler).pointeur_signal_ecriture = 3030: ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1) 3031: % LONGUEUR_QUEUE_SIGNAUX; 3032: pthread_mutex_unlock(&mutex_interruptions); 3033: 3034: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 3035: if (sem_post(&((*s_queue_signaux).signalisation)) != 0) 3036: { 3037: return(1); 3038: } 3039: # else 3040: if (sem_post(semaphore_signalisation) != 0) 3041: { 3042: return(1); 3043: } 3044: # endif 3045: 3046: return(0); 3047: } 3048: 3049: 3050: /* 3051: ================================================================================ 3052: Fonction créant un segment de mémoire partagée destiné à contenir 3053: la queue des signaux. 3054: ================================================================================ 3055: Entrée : structure de description du processus 3056: -------------------------------------------------------------------------------- 3057: Sortie : Néant 3058: -------------------------------------------------------------------------------- 3059: Effet de bord : Néant 3060: ================================================================================ 3061: */ 3062: 3063: void 3064: creation_queue_signaux(struct_processus *s_etat_processus) 3065: { 3066: pthread_attr_t attributs; 3067: 3068: unsigned char *nom; 3069: 3070: racine_segment = (*s_etat_processus).chemin_fichiers_temporaires; 3071: 3072: # ifndef IPCS_SYSV // POSIX 3073: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires, 3074: getpid())) == NULL) 3075: { 3076: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3077: return; 3078: } 3079: 3080: if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_EXCL, 3081: S_IRUSR | S_IWUSR)) == -1) 3082: { 3083: free(nom); 3084: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3085: return; 3086: } 3087: 3088: if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1) 3089: { 3090: free(nom); 3091: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3092: return; 3093: } 3094: 3095: s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux), 3096: PROT_READ | PROT_WRITE, MAP_SHARED, f_queue_signaux, 0); 3097: 3098: if (((void *) s_queue_signaux) == ((void *) -1)) 3099: { 3100: if (shm_unlink(nom) == -1) 3101: { 3102: free(nom); 3103: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3104: return; 3105: } 3106: 3107: free(nom); 3108: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3109: return; 3110: } 3111: 3112: free(nom); 3113: 3114: # ifndef SEMAPHORES_NOMMES 3115: sem_init(&((*s_queue_signaux).semaphore), 1, 1); 3116: sem_init(&((*s_queue_signaux).signalisation), 1, 0); 3117: # else 3118: if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE)) 3119: == SEM_FAILED) 3120: { 3121: (*s_etat_processus).erreur_systeme = d_es_processus; 3122: return; 3123: } 3124: 3125: if ((semaphore_signalisation = sem_init2(1, getpid(), 3126: SEM_SIGNALISATION)) == SEM_FAILED) 3127: { 3128: (*s_etat_processus).erreur_systeme = d_es_processus; 3129: return; 3130: } 3131: # endif 3132: 3133: (*s_queue_signaux).pointeur_lecture = 0; 3134: (*s_queue_signaux).pointeur_ecriture = 0; 3135: (*s_queue_signaux).requete_arret = d_faux; 3136: 3137: if (msync(s_queue_signaux, sizeof(struct_queue_signaux), 0)) 3138: { 3139: (*s_etat_processus).erreur_systeme = d_es_processus; 3140: return; 3141: } 3142: # else // IPCS_SYSV 3143: # ifndef OS2 3144: int segment; 3145: int support; 3146: 3147: key_t clef; 3148: 3149: // Création d'un segment de données associé au PID du processus 3150: // courant 3151: 3152: if ((nom = nom_segment((*s_etat_processus) 3153: .chemin_fichiers_temporaires, getpid())) == NULL) 3154: { 3155: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3156: return; 3157: } 3158: 3159: if ((support = open(nom, O_RDWR | O_CREAT | O_EXCL, 3160: S_IRUSR | S_IWUSR)) == -1) 3161: { 3162: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; 3163: return; 3164: } 3165: 3166: if ((clef = ftok(nom, 1)) == -1) 3167: { 3168: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3169: return; 3170: } 3171: 3172: close(support); 3173: free(nom); 3174: 3175: if ((segment = shmget(clef, sizeof(struct_queue_signaux), 3176: IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1) 3177: { 3178: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3179: return; 3180: } 3181: 3182: s_queue_signaux = shmat(segment, NULL, 0); 3183: f_queue_signaux = segment; 3184: 3185: if (((void *) s_queue_signaux) == ((void *) -1)) 3186: { 3187: if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1) 3188: { 3189: (*s_etat_processus).erreur_systeme = 3190: d_es_allocation_memoire; 3191: return; 3192: } 3193: 3194: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3195: return; 3196: } 3197: 3198: sem_init(&((*s_queue_signaux).semaphore), 1, 1); 3199: sem_init(&((*s_queue_signaux).signalisation), 1, 0); 3200: (*s_queue_signaux).pointeur_lecture = 0; 3201: (*s_queue_signaux).pointeur_ecriture = 0; 3202: (*s_queue_signaux).requete_arret = d_faux; 3203: # else // OS/2 3204: if ((nom = nom_segment(NULL, getpid())) == NULL) 3205: { 3206: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3207: return; 3208: } 3209: 3210: if (DosAllocSharedMem((PVOID) &s_queue_signaux, nom, 3211: sizeof(struct_queue_signaux), 3212: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0) 3213: { 3214: free(nom); 3215: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3216: return; 3217: } 3218: 3219: free(nom); 3220: 3221: sem_init(&((*s_queue_signaux).semaphore), 1, 1); 3222: sem_init(&((*s_queue_signaux).signalisation), 1, 0); 3223: (*s_queue_signaux).pointeur_lecture = 0; 3224: (*s_queue_signaux).pointeur_ecriture = 0; 3225: (*s_queue_signaux).requete_arret = d_faux; 3226: # endif 3227: # endif 3228: 3229: // Lancement du thread de récupération des signaux. 3230: 3231: if (pthread_attr_init(&attributs) != 0) 3232: { 3233: (*s_etat_processus).erreur_systeme = d_es_processus; 3234: return; 3235: } 3236: 3237: if (pthread_attr_setdetachstate(&attributs, 3238: PTHREAD_CREATE_JOINABLE) != 0) 3239: { 3240: (*s_etat_processus).erreur_systeme = d_es_processus; 3241: return; 3242: } 3243: 3244: # ifdef SCHED_OTHER 3245: if (pthread_attr_setschedpolicy(&attributs, SCHED_OTHER) != 0) 3246: { 3247: (*s_etat_processus).erreur_systeme = d_es_processus; 3248: return; 3249: } 3250: # endif 3251: 3252: # ifdef PTHREAD_EXPLICIT_SCHED 3253: if (pthread_attr_setinheritsched(&attributs, PTHREAD_EXPLICIT_SCHED) != 0) 3254: { 3255: (*s_etat_processus).erreur_systeme = d_es_processus; 3256: return; 3257: } 3258: # endif 3259: 3260: # ifdef PTHREAD_SCOPE_SYSTEM 3261: if (pthread_attr_setscope(&attributs, PTHREAD_SCOPE_SYSTEM) != 0) 3262: { 3263: (*s_etat_processus).erreur_systeme = d_es_processus; 3264: return; 3265: } 3266: # endif 3267: 3268: if (pthread_attr_destroy(&attributs) != 0) 3269: { 3270: (*s_etat_processus).erreur_systeme = d_es_processus; 3271: return; 3272: } 3273: 3274: if (pthread_create(&((*s_queue_signaux).thread_signaux), &attributs, 3275: thread_surveillance_signaux, s_etat_processus) != 0) 3276: { 3277: (*s_etat_processus).erreur_systeme = d_es_processus; 3278: return; 3279: } 3280: 3281: return; 3282: } 3283: 3284: 3285: /* 3286: ================================================================================ 3287: Fonction libérant le segment de mémoire partagée destiné à contenir 3288: la queue des signaux. 3289: ================================================================================ 3290: Entrée : structure de description du processus 3291: -------------------------------------------------------------------------------- 3292: Sortie : Néant 3293: -------------------------------------------------------------------------------- 3294: Effet de bord : Néant 3295: ================================================================================ 3296: */ 3297: 3298: void 3299: liberation_queue_signaux(struct_processus *s_etat_processus) 3300: { 3301: // Incrémenter le sémaphore pour être sûr de le débloquer. 3302: 3303: (*s_queue_signaux).requete_arret = d_vrai; 3304: 3305: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 3306: sem_post(&((*s_queue_signaux).signalisation)); 3307: # else 3308: sem_post(semaphore_signalisation); 3309: # endif 3310: 3311: pthread_join((*s_queue_signaux).thread_signaux, NULL); 3312: 3313: # ifdef IPCS_SYSV // SystemV 3314: # ifndef OS2 3315: if (shmdt(s_queue_signaux) == -1) 3316: { 3317: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3318: return; 3319: } 3320: # else // OS/2 3321: # endif 3322: # else // POSIX 3323: # ifndef SEMAPHORES_NOMMES 3324: sem_close(&((*s_queue_signaux).semaphore)); 3325: sem_close(&((*s_queue_signaux).signalisation)); 3326: # else 3327: sem_close(semaphore_queue_signaux); 3328: sem_close(semaphore_signalisation); 3329: # endif 3330: 3331: if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0) 3332: { 3333: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3334: return; 3335: } 3336: 3337: close(f_queue_signaux); 3338: # endif 3339: 3340: return; 3341: } 3342: 3343: 3344: /* 3345: ================================================================================ 3346: Fonction détruisant le segment de mémoire partagée destiné à contenir 3347: la queue des signaux. 3348: ================================================================================ 3349: Entrée : structure de description du processus 3350: -------------------------------------------------------------------------------- 3351: Sortie : Néant 3352: -------------------------------------------------------------------------------- 3353: Effet de bord : Néant 3354: ================================================================================ 3355: */ 3356: 3357: void 3358: destruction_queue_signaux(struct_processus *s_etat_processus) 3359: { 3360: # ifndef OS2 3361: unsigned char *nom; 3362: # endif 3363: 3364: // Incrémenter le sémaphore pour être sûr de le débloquer. 3365: 3366: (*s_queue_signaux).requete_arret = d_vrai; 3367: 3368: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV) 3369: sem_post(&((*s_queue_signaux).signalisation)); 3370: # else 3371: sem_post(semaphore_signalisation); 3372: # endif 3373: 3374: pthread_join((*s_queue_signaux).thread_signaux, NULL); 3375: 3376: # ifdef IPCS_SYSV // SystemV 3377: # ifndef OS2 3378: // Il faut commencer par éliminer le sémaphore. 3379: 3380: if (semctl((*s_queue_signaux).semaphore.sem, 0, IPC_RMID) == -1) 3381: { 3382: (*s_etat_processus).erreur_systeme = d_es_processus; 3383: return; 3384: } 3385: 3386: unlink((*s_queue_signaux).semaphore.path); 3387: free((*s_queue_signaux).semaphore.path); 3388: 3389: if (semctl((*s_queue_signaux).signalisation.sem, 0, IPC_RMID) == -1) 3390: { 3391: (*s_etat_processus).erreur_systeme = d_es_processus; 3392: return; 3393: } 3394: 3395: unlink((*s_queue_signaux).signalisation.path); 3396: free((*s_queue_signaux).signalisation.path); 3397: 3398: if (shmdt(s_queue_signaux) == -1) 3399: { 3400: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3401: return; 3402: } 3403: 3404: if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1) 3405: { 3406: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3407: return; 3408: } 3409: 3410: if ((nom = nom_segment((*s_etat_processus) 3411: .chemin_fichiers_temporaires, getpid())) == NULL) 3412: { 3413: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3414: return; 3415: } 3416: 3417: unlink(nom); 3418: free(nom); 3419: # else 3420: sem_close(&((*s_queue_signaux).semaphore)); 3421: sem_destroy(&((*s_queue_signaux).semaphore)); 3422: 3423: sem_close(&((*s_queue_signaux).signalisation)); 3424: sem_destroy(&((*s_queue_signaux).signalisation)); 3425: 3426: if (DosFreeMem(s_queue_signaux) != 0) 3427: { 3428: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3429: return; 3430: } 3431: # endif 3432: # else // POSIX 3433: # ifndef SEMAPHORES_NOMMES 3434: sem_close(&((*s_queue_signaux).semaphore)); 3435: sem_destroy(&((*s_queue_signaux).semaphore)); 3436: 3437: sem_close(&((*s_queue_signaux).signalisation)); 3438: sem_destroy(&((*s_queue_signaux).signalisation)); 3439: # else 3440: sem_close(semaphore_queue_signaux); 3441: sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE); 3442: 3443: sem_close(semaphore_signalisation); 3444: sem_destroy2(semaphore_signalisation, getpid(), SEM_SIGNALISATION); 3445: # endif 3446: 3447: if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0) 3448: { 3449: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3450: return; 3451: } 3452: 3453: if ((nom = nom_segment(NULL, getpid())) == NULL) 3454: { 3455: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3456: return; 3457: } 3458: 3459: close(f_queue_signaux); 3460: 3461: if (shm_unlink(nom) != 0) 3462: { 3463: free(nom); 3464: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 3465: return; 3466: } 3467: 3468: free(nom); 3469: # endif 3470: 3471: return; 3472: } 3473: 3474: // vim: ts=4