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