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