1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.3
4: Copyright (C) 1989-2011 Dr. BERTRAND Joël
5:
6: This file is part of RPL/2.
7:
8: RPL/2 is free software; you can redistribute it and/or modify it
9: under the terms of the CeCILL V2 License as published by the french
10: CEA, CNRS and INRIA.
11:
12: RPL/2 is distributed in the hope that it will be useful, but WITHOUT
13: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License
15: for more details.
16:
17: You should have received a copy of the CeCILL License
18: along with RPL/2. If not, write to info@cecill.info.
19: ================================================================================
20: */
21:
22:
23: #include "rpl-conv.h"
24:
25:
26: /*
27: ================================================================================
28: Procédures de gestion par thread des variables issues des gestionnaires
29: de signaux
30: ================================================================================
31: Entrée : variable globale
32: --------------------------------------------------------------------------------
33: Sortie : variable globale modifiée
34: --------------------------------------------------------------------------------
35: Effets de bord : néant
36: ================================================================================
37: */
38:
39: typedef struct thread
40: {
41: pid_t pid;
42: pthread_t tid;
43:
44: logical1 thread_principal;
45:
46: struct_processus *s_etat_processus;
47: } struct_thread;
48:
49: typedef struct liste_chainee_volatile
50: {
51: volatile struct liste_chainee_volatile *suivant;
52: volatile void *donnee;
53: } struct_liste_chainee_volatile;
54:
55:
56: static volatile struct_liste_chainee_volatile *liste_threads
57: = NULL;
58: static volatile struct_liste_chainee_volatile *liste_threads_surveillance
59: = NULL;
60: static volatile int code_erreur_gsl = 0;
61:
62: static pthread_mutex_t mutex_interruptions
63: = PTHREAD_MUTEX_INITIALIZER;
64:
65: void
66: modification_pid_thread_pere(struct_processus *s_etat_processus)
67: {
68: // La variable existe toujours et aucun thread concurrent ne peut
69: // la modifier puisque cette routine ne peut être appelée que depuis
70: // DAEMON.
71:
72: (*((struct_thread *) (*liste_threads).donnee)).pid =
73: (*s_etat_processus).pid_processus_pere;
74:
75: return;
76: }
77:
78: void
79: insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)
80: {
81: volatile struct_liste_chainee_volatile *l_nouvel_objet;
82:
83: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
84: == NULL)
85: {
86: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
87: return;
88: }
89:
90: if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)
91: {
92: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
93: return;
94: }
95:
96: (*((struct_thread *) (*l_nouvel_objet).donnee)).pid = getpid();
97: (*((struct_thread *) (*l_nouvel_objet).donnee)).tid = pthread_self();
98: (*((struct_thread *) (*l_nouvel_objet).donnee)).thread_principal =
99: thread_principal;
100: (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
101: s_etat_processus;
102:
103: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
104: {
105: (*s_etat_processus).erreur_systeme = d_es_processus;
106: return;
107: }
108:
109: (*l_nouvel_objet).suivant = liste_threads;
110: liste_threads = l_nouvel_objet;
111:
112: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
113: {
114: (*s_etat_processus).erreur_systeme = d_es_processus;
115: return;
116: }
117:
118: return;
119: }
120:
121: void
122: insertion_thread_surveillance(struct_processus *s_etat_processus,
123: struct_descripteur_thread *s_argument_thread)
124: {
125: volatile struct_liste_chainee_volatile *l_nouvel_objet;
126:
127: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
128: == NULL)
129: {
130: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
131: return;
132: }
133:
134: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
135: {
136: (*s_etat_processus).erreur_systeme = d_es_processus;
137: return;
138: }
139:
140: pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references));
141: (*s_argument_thread).nombre_references++;
142: pthread_mutex_unlock(&((*s_argument_thread).mutex_nombre_references));
143:
144: (*l_nouvel_objet).suivant = liste_threads_surveillance;
145: (*l_nouvel_objet).donnee = (void *) s_argument_thread;
146:
147: liste_threads_surveillance = l_nouvel_objet;
148:
149: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
150: {
151: (*s_etat_processus).erreur_systeme = d_es_processus;
152: return;
153: }
154:
155: return;
156: }
157:
158: void
159: retrait_thread(struct_processus *s_etat_processus)
160: {
161: volatile struct_liste_chainee_volatile *l_element_precedent;
162: volatile struct_liste_chainee_volatile *l_element_courant;
163:
164: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
165: {
166: (*s_etat_processus).erreur_systeme = d_es_processus;
167: return;
168: }
169:
170: l_element_precedent = NULL;
171: l_element_courant = liste_threads;
172:
173: while(l_element_courant != NULL)
174: {
175: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
176: == getpid()) && (pthread_equal((*((struct_thread *)
177: (*l_element_courant).donnee)).tid, pthread_self()) != 0))
178: {
179: break;
180: }
181:
182: l_element_precedent = l_element_courant;
183: l_element_courant = (*l_element_courant).suivant;
184: }
185:
186: if (l_element_courant == NULL)
187: {
188: pthread_mutex_unlock(&mutex_liste_threads);
189: (*s_etat_processus).erreur_systeme = d_es_processus;
190: return;
191: }
192:
193: if (l_element_precedent == NULL)
194: {
195: liste_threads = (*l_element_courant).suivant;
196: }
197: else
198: {
199: (*l_element_precedent).suivant = (*l_element_courant).suivant;
200: }
201:
202: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
203: {
204: (*s_etat_processus).erreur_systeme = d_es_processus;
205: return;
206: }
207:
208: free((void *) (*l_element_courant).donnee);
209: free((struct_liste_chainee_volatile *) l_element_courant);
210:
211: return;
212: }
213:
214: void
215: retrait_thread_surveillance(struct_processus *s_etat_processus,
216: struct_descripteur_thread *s_argument_thread)
217: {
218: volatile struct_liste_chainee_volatile *l_element_precedent;
219: volatile struct_liste_chainee_volatile *l_element_courant;
220:
221: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
222: {
223: (*s_etat_processus).erreur_systeme = d_es_processus;
224: return;
225: }
226:
227: l_element_precedent = NULL;
228: l_element_courant = liste_threads_surveillance;
229:
230: while(l_element_courant != NULL)
231: {
232: if ((*l_element_courant).donnee == (void *) s_argument_thread)
233: {
234: break;
235: }
236:
237: l_element_precedent = l_element_courant;
238: l_element_courant = (*l_element_courant).suivant;
239: }
240:
241: if (l_element_courant == NULL)
242: {
243: pthread_mutex_unlock(&mutex_liste_threads);
244: (*s_etat_processus).erreur_systeme = d_es_processus;
245: return;
246: }
247:
248: if (l_element_precedent == NULL)
249: {
250: liste_threads_surveillance = (*l_element_courant).suivant;
251: }
252: else
253: {
254: (*l_element_precedent).suivant = (*l_element_courant).suivant;
255: }
256:
257: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
258: != 0)
259: {
260: pthread_mutex_unlock(&mutex_liste_threads);
261: (*s_etat_processus).erreur_systeme = d_es_processus;
262: return;
263: }
264:
265: (*s_argument_thread).nombre_references--;
266:
267: BUG((*s_argument_thread).nombre_references < 0,
268: printf("(*s_argument_thread).nombre_references = %d\n",
269: (int) (*s_argument_thread).nombre_references));
270:
271: if ((*s_argument_thread).nombre_references == 0)
272: {
273: if (pthread_mutex_unlock(&((*s_argument_thread)
274: .mutex_nombre_references)) != 0)
275: {
276: pthread_mutex_unlock(&mutex_liste_threads);
277: (*s_etat_processus).erreur_systeme = d_es_processus;
278: return;
279: }
280:
281: pthread_mutex_destroy(&((*s_argument_thread).mutex));
282: pthread_mutex_destroy(&((*s_argument_thread).mutex_nombre_references));
283: free(s_argument_thread);
284: }
285: else
286: {
287: if (pthread_mutex_unlock(&((*s_argument_thread)
288: .mutex_nombre_references)) != 0)
289: {
290: pthread_mutex_unlock(&mutex_liste_threads);
291: (*s_etat_processus).erreur_systeme = d_es_processus;
292: return;
293: }
294: }
295:
296: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
297: {
298: (*s_etat_processus).erreur_systeme = d_es_processus;
299: return;
300: }
301:
302: free((struct_liste_chainee_volatile *) l_element_courant);
303: return;
304: }
305:
306: void
307: verrouillage_threads_concurrents(struct_processus *s_etat_processus)
308: {
309: volatile struct_liste_chainee_volatile *l_element_courant;
310:
311: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
312: {
313: (*s_etat_processus).erreur_systeme = d_es_processus;
314: return;
315: }
316:
317: l_element_courant = liste_threads;
318:
319: while(l_element_courant != NULL)
320: {
321: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
322: == getpid()) && (pthread_equal((*((struct_thread *)
323: (*l_element_courant).donnee)).tid, pthread_self()) == 0))
324: {
325: if (pthread_mutex_lock(&((*(*((struct_thread *) (*l_element_courant)
326: .donnee)).s_etat_processus).mutex_fork)) == -1)
327: {
328: (*s_etat_processus).erreur_systeme = d_es_processus;
329: return;
330: }
331: }
332:
333: l_element_courant = (*l_element_courant).suivant;
334: }
335:
336: return;
337: }
338:
339: void
340: deverrouillage_threads_concurrents(struct_processus *s_etat_processus)
341: {
342: volatile struct_liste_chainee_volatile *l_element_courant;
343:
344: l_element_courant = liste_threads;
345:
346: while(l_element_courant != NULL)
347: {
348: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
349: == getpid()) && (pthread_equal((*((struct_thread *)
350: (*l_element_courant).donnee)).tid, pthread_self()) == 0))
351: {
352: if (pthread_mutex_unlock(&((*(*((struct_thread *)
353: (*l_element_courant).donnee)).s_etat_processus)
354: .mutex_fork)) != 0)
355: {
356: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
357: {
358: (*s_etat_processus).erreur_systeme = d_es_processus;
359: return;
360: }
361:
362: (*s_etat_processus).erreur_systeme = d_es_processus;
363: return;
364: }
365: }
366:
367: l_element_courant = (*l_element_courant).suivant;
368: }
369:
370: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
371: {
372: (*s_etat_processus).erreur_systeme = d_es_processus;
373: return;
374: }
375:
376: return;
377: }
378:
379: void
380: liberation_threads(struct_processus *s_etat_processus)
381: {
382: logical1 suppression_variables_partagees;
383:
384: struct_descripteur_thread *s_argument_thread;
385:
386: struct_processus *candidat;
387:
388: unsigned long i;
389:
390: void *element_candidat;
391: void *element_courant;
392: void *element_suivant;
393:
394: volatile struct_liste_chainee_volatile *l_element_courant;
395: volatile struct_liste_chainee_volatile *l_element_suivant;
396:
397: if (pthread_mutex_lock(&mutex_liste_threads) == -1)
398: {
399: (*s_etat_processus).erreur_systeme = d_es_processus;
400: return;
401: }
402:
403: l_element_courant = liste_threads;
404: suppression_variables_partagees = d_faux;
405:
406: while(l_element_courant != NULL)
407: {
408: if ((*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus
409: != s_etat_processus)
410: {
411: candidat = s_etat_processus;
412: s_etat_processus = (*((struct_thread *)
413: (*l_element_courant).donnee)).s_etat_processus;
414: free((*s_etat_processus).localisation);
415:
416: // (*s_etat_processus).instruction_courante peut pointer sur
417: // n'importe quoi (une instruction courante ou un champ d'une
418: // structure objet). On ne le libère pas quitte à avoir une
419: // petite fuite mémoire dans le processus fils.
420:
421: if ((*s_etat_processus).instruction_courante != NULL)
422: {
423: //free((*s_etat_processus).instruction_courante);
424: }
425:
426: close((*s_etat_processus).pipe_acquittement);
427: close((*s_etat_processus).pipe_donnees);
428: close((*s_etat_processus).pipe_injections);
429: close((*s_etat_processus).pipe_nombre_injections);
430: close((*s_etat_processus).pipe_interruptions);
431: close((*s_etat_processus).pipe_nombre_objets_attente);
432: close((*s_etat_processus).pipe_nombre_interruptions_attente);
433:
434: liberation(s_etat_processus, (*s_etat_processus).at_exit);
435:
436: if ((*s_etat_processus).nom_fichier_impression != NULL)
437: {
438: free((*s_etat_processus).nom_fichier_impression);
439: }
440:
441: while((*s_etat_processus).fichiers_graphiques != NULL)
442: {
443: free((*(*s_etat_processus).fichiers_graphiques).nom);
444:
445: if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL)
446: {
447: free((*(*s_etat_processus).fichiers_graphiques).legende);
448: }
449:
450: element_courant = (*s_etat_processus).fichiers_graphiques;
451: (*s_etat_processus).fichiers_graphiques =
452: (*(*s_etat_processus).fichiers_graphiques).suivant;
453:
454: free(element_courant);
455: }
456:
457: if ((*s_etat_processus).entree_standard != NULL)
458: {
459: pclose((*s_etat_processus).entree_standard);
460: }
461:
462: if ((*s_etat_processus).generateur_aleatoire != NULL)
463: {
464: liberation_generateur_aleatoire(s_etat_processus);
465: }
466:
467: if ((*s_etat_processus).instruction_derniere_erreur != NULL)
468: {
469: free((*s_etat_processus).instruction_derniere_erreur);
470: (*s_etat_processus).instruction_derniere_erreur = NULL;
471: }
472:
473: element_courant = (void *) (*s_etat_processus)
474: .l_base_pile_processus;
475: while(element_courant != NULL)
476: {
477: s_argument_thread = (struct_descripteur_thread *)
478: (*((struct_liste_chainee *) element_courant)).donnee;
479:
480: if (pthread_mutex_lock(&((*s_argument_thread)
481: .mutex_nombre_references)) != 0)
482: {
483: (*s_etat_processus).erreur_systeme = d_es_processus;
484: pthread_mutex_unlock(&mutex_liste_threads);
485: return;
486: }
487:
488: (*s_argument_thread).nombre_references--;
489:
490: BUG((*s_argument_thread).nombre_references < 0,
491: printf("(*s_argument_thread).nombre_references = %d\n",
492: (int) (*s_argument_thread).nombre_references));
493:
494: if ((*s_argument_thread).nombre_references == 0)
495: {
496: close((*s_argument_thread).pipe_objets[0]);
497: close((*s_argument_thread).pipe_acquittement[1]);
498: close((*s_argument_thread).pipe_injections[1]);
499: close((*s_argument_thread).pipe_nombre_injections[1]);
500: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
501: close((*s_argument_thread).pipe_interruptions[0]);
502: close((*s_argument_thread)
503: .pipe_nombre_interruptions_attente[0]);
504:
505: if (pthread_mutex_unlock(&((*s_argument_thread)
506: .mutex_nombre_references)) != 0)
507: {
508: (*s_etat_processus).erreur_systeme = d_es_processus;
509: pthread_mutex_unlock(&mutex_liste_threads);
510: return;
511: }
512:
513: pthread_mutex_destroy(&((*s_argument_thread).mutex));
514: pthread_mutex_destroy(&((*s_argument_thread)
515: .mutex_nombre_references));
516:
517: if ((*s_argument_thread).processus_detache == d_faux)
518: {
519: if ((*s_argument_thread).destruction_objet == d_vrai)
520: {
521: liberation(s_etat_processus, (*s_argument_thread)
522: .argument);
523: }
524: }
525:
526: free(s_argument_thread);
527: }
528: else
529: {
530: if (pthread_mutex_unlock(&((*s_argument_thread)
531: .mutex_nombre_references)) != 0)
532: {
533: (*s_etat_processus).erreur_systeme = d_es_processus;
534: pthread_mutex_unlock(&mutex_liste_threads);
535: return;
536: }
537: }
538:
539: element_suivant = (*((struct_liste_chainee *) element_courant))
540: .suivant;
541: free(element_courant);
542: element_courant = element_suivant;
543: }
544:
545: (*s_etat_processus).l_base_pile_processus = NULL;
546:
547: pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));
548: pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));
549: liberation(s_etat_processus, (*s_etat_processus).indep);
550:
551: pthread_mutex_trylock(&((*(*s_etat_processus).depend).mutex));
552: pthread_mutex_unlock(&((*(*s_etat_processus).depend).mutex));
553: liberation(s_etat_processus, (*s_etat_processus).depend);
554:
555: free((*s_etat_processus).label_x);
556: free((*s_etat_processus).label_y);
557: free((*s_etat_processus).label_z);
558: free((*s_etat_processus).titre);
559: free((*s_etat_processus).legende);
560:
561: pthread_mutex_trylock(&((*(*s_etat_processus)
562: .parametres_courbes_de_niveau).mutex));
563: pthread_mutex_unlock(&((*(*s_etat_processus)
564: .parametres_courbes_de_niveau).mutex));
565: liberation(s_etat_processus, (*s_etat_processus)
566: .parametres_courbes_de_niveau);
567:
568: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
569: {
570: if ((*s_etat_processus).corps_interruptions[i] != NULL)
571: {
572: pthread_mutex_trylock(&((*(*s_etat_processus)
573: .corps_interruptions[i]).mutex));
574: pthread_mutex_unlock(&((*(*s_etat_processus)
575: .corps_interruptions[i]).mutex));
576:
577: liberation(s_etat_processus,
578: (*s_etat_processus).corps_interruptions[i]);
579: }
580:
581: element_courant = (*s_etat_processus)
582: .pile_origine_interruptions[i];
583:
584: while(element_courant != NULL)
585: {
586: element_suivant = (*((struct_liste_chainee *)
587: element_courant)).suivant;
588:
589: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
590: element_courant)).donnee).mutex));
591: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
592: element_courant)).donnee).mutex));
593:
594: liberation(s_etat_processus,
595: (*((struct_liste_chainee *) element_courant))
596: .donnee);
597: free(element_courant);
598:
599: element_courant = element_suivant;
600: }
601: }
602:
603: liberation_arbre_variables(s_etat_processus,
604: (*s_etat_processus).s_arbre_variables, d_faux);
605:
606: for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
607: {
608: pthread_mutex_trylock(&((*(*s_etat_processus)
609: .s_liste_variables_statiques[i].objet).mutex));
610: pthread_mutex_unlock(&((*(*s_etat_processus)
611: .s_liste_variables_statiques[i].objet).mutex));
612:
613: liberation(s_etat_processus, (*s_etat_processus)
614: .s_liste_variables_statiques[i].objet);
615: free((*s_etat_processus).s_liste_variables_statiques[i].nom);
616: }
617:
618: free((*s_etat_processus).s_liste_variables_statiques);
619:
620: // Ne peut être effacé qu'une seule fois
621: if (suppression_variables_partagees == d_faux)
622: {
623: suppression_variables_partagees = d_vrai;
624:
625: for(i = 0; i < (*(*s_etat_processus)
626: .s_liste_variables_partagees).nombre_variables; i++)
627: {
628: pthread_mutex_trylock(&((*(*(*s_etat_processus)
629: .s_liste_variables_partagees).table[i].objet)
630: .mutex));
631: pthread_mutex_unlock(&((*(*(*s_etat_processus)
632: .s_liste_variables_partagees).table[i].objet)
633: .mutex));
634:
635: liberation(s_etat_processus, (*(*s_etat_processus)
636: .s_liste_variables_partagees).table[i].objet);
637: free((*(*s_etat_processus).s_liste_variables_partagees)
638: .table[i].nom);
639: }
640:
641: if ((*(*s_etat_processus).s_liste_variables_partagees).table
642: != NULL)
643: {
644: free((struct_variable_partagee *) (*(*s_etat_processus)
645: .s_liste_variables_partagees).table);
646: }
647:
648: pthread_mutex_trylock(&((*(*s_etat_processus)
649: .s_liste_variables_partagees).mutex));
650: pthread_mutex_unlock(&((*(*s_etat_processus)
651: .s_liste_variables_partagees).mutex));
652: }
653:
654: element_courant = (*s_etat_processus).l_base_pile;
655: while(element_courant != NULL)
656: {
657: element_suivant = (*((struct_liste_chainee *)
658: element_courant)).suivant;
659:
660: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
661: element_courant)).donnee).mutex));
662: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
663: element_courant)).donnee).mutex));
664:
665: liberation(s_etat_processus,
666: (*((struct_liste_chainee *)
667: element_courant)).donnee);
668: free((struct_liste_chainee *) element_courant);
669:
670: element_courant = element_suivant;
671: }
672:
673: element_courant = (*s_etat_processus).l_base_pile_contextes;
674: while(element_courant != NULL)
675: {
676: element_suivant = (*((struct_liste_chainee *)
677: element_courant)).suivant;
678:
679: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
680: element_courant)).donnee).mutex));
681: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
682: element_courant)).donnee).mutex));
683: liberation(s_etat_processus, (*((struct_liste_chainee *)
684: element_courant)).donnee);
685: free((struct_liste_chainee *) element_courant);
686:
687: element_courant = element_suivant;
688: }
689:
690: element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
691: while(element_courant != NULL)
692: {
693: element_suivant = (*((struct_liste_chainee *)
694: element_courant)).suivant;
695:
696: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
697: element_courant)).donnee).mutex));
698: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
699: element_courant)).donnee).mutex));
700: liberation(s_etat_processus,
701: (*((struct_liste_chainee *)
702: element_courant)).donnee);
703: free((struct_liste_chainee *) element_courant);
704:
705: element_courant = element_suivant;
706: }
707:
708: for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
709: i++)
710: {
711: free((*s_etat_processus).s_instructions_externes[i].nom);
712: free((*s_etat_processus).s_instructions_externes[i]
713: .nom_bibliotheque);
714: }
715:
716: if ((*s_etat_processus).nombre_instructions_externes != 0)
717: {
718: free((*s_etat_processus).s_instructions_externes);
719: }
720:
721: element_courant = (*s_etat_processus).s_bibliotheques;
722: while(element_courant != NULL)
723: {
724: element_suivant = (*((struct_liste_chainee *)
725: element_courant)).suivant;
726:
727: element_candidat = (*candidat).s_bibliotheques;
728: while(element_candidat != NULL)
729: {
730: if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
731: element_courant)).donnee))
732: .descripteur == (*((struct_bibliotheque *)
733: (*((struct_liste_chainee *) element_candidat))
734: .donnee)).descripteur) &&
735: ((*((struct_bibliotheque *)
736: (*((struct_liste_chainee *) element_courant))
737: .donnee)).pid == (*((struct_bibliotheque *)
738: (*((struct_liste_chainee *) element_candidat))
739: .donnee)).pid) && (pthread_equal(
740: (*((struct_bibliotheque *)
741: (*((struct_liste_chainee *) element_courant))
742: .donnee)).tid, (*((struct_bibliotheque *)
743: (*((struct_liste_chainee *) element_candidat))
744: .donnee)).tid) != 0))
745: {
746: break;
747: }
748:
749: element_candidat = (*((struct_liste_chainee *)
750: element_candidat)).suivant;
751: }
752:
753: if (element_candidat == NULL)
754: {
755: dlclose((*((struct_bibliotheque *)
756: (*((struct_liste_chainee *) element_courant))
757: .donnee)).descripteur);
758: }
759:
760: free((*((struct_bibliotheque *)
761: (*((struct_liste_chainee *)
762: element_courant)).donnee)).nom);
763: free((*((struct_liste_chainee *) element_courant)).donnee);
764: free(element_courant);
765:
766: element_courant = element_suivant;
767: }
768:
769: element_courant = (*s_etat_processus).l_base_pile_last;
770: while(element_courant != NULL)
771: {
772: element_suivant = (*((struct_liste_chainee *)
773: element_courant)).suivant;
774:
775: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
776: element_courant)).donnee).mutex));
777: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
778: element_courant)).donnee).mutex));
779: liberation(s_etat_processus,
780: (*((struct_liste_chainee *) element_courant)).donnee);
781: free(element_courant);
782:
783: element_courant = element_suivant;
784: }
785:
786: element_courant = (*s_etat_processus).l_base_pile_systeme;
787: while(element_courant != NULL)
788: {
789: element_suivant = (*((struct_liste_pile_systeme *)
790: element_courant)).suivant;
791:
792: if ((*((struct_liste_pile_systeme *)
793: element_courant)).indice_boucle != NULL)
794: {
795: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
796: element_courant)).indice_boucle).mutex));
797: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
798: element_courant)).indice_boucle).mutex));
799: }
800:
801: liberation(s_etat_processus,
802: (*((struct_liste_pile_systeme *)
803: element_courant)).indice_boucle);
804:
805: if ((*((struct_liste_pile_systeme *)
806: element_courant)).limite_indice_boucle != NULL)
807: {
808: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
809: element_courant)).limite_indice_boucle).mutex));
810: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
811: element_courant)).limite_indice_boucle).mutex));
812: }
813:
814: liberation(s_etat_processus,
815: (*((struct_liste_pile_systeme *)
816: element_courant)).limite_indice_boucle);
817:
818: if ((*((struct_liste_pile_systeme *)
819: element_courant)).objet_de_test != NULL)
820: {
821: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
822: element_courant)).objet_de_test).mutex));
823: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
824: element_courant)).objet_de_test).mutex));
825: }
826:
827: liberation(s_etat_processus,
828: (*((struct_liste_pile_systeme *)
829: element_courant)).objet_de_test);
830:
831: if ((*((struct_liste_pile_systeme *)
832: element_courant)).nom_variable != NULL)
833: {
834: free((*((struct_liste_pile_systeme *)
835: element_courant)).nom_variable);
836: }
837:
838: free(element_courant);
839:
840: element_courant = element_suivant;
841: }
842:
843: element_courant = (*s_etat_processus).s_fichiers;
844: while(element_courant != NULL)
845: {
846: element_suivant = (*((struct_liste_chainee *)
847: element_courant)).suivant;
848:
849: element_candidat = (*candidat).s_fichiers;
850: while(element_candidat != NULL)
851: {
852: if (((*((struct_descripteur_fichier *)
853: (*((struct_liste_chainee *) element_courant))
854: .donnee)).pid ==
855: (*((struct_descripteur_fichier *)
856: (*((struct_liste_chainee *) element_candidat))
857: .donnee)).pid) && (pthread_equal(
858: (*((struct_descripteur_fichier *)
859: (*((struct_liste_chainee *) element_courant))
860: .donnee)).tid, (*((struct_descripteur_fichier *)
861: (*((struct_liste_chainee *) element_candidat))
862: .donnee)).tid) != 0))
863: {
864: if ((*((struct_descripteur_fichier *)
865: (*((struct_liste_chainee *) element_courant))
866: .donnee)).type ==
867: (*((struct_descripteur_fichier *)
868: (*((struct_liste_chainee *) element_candidat))
869: .donnee)).type)
870: {
871: if ((*((struct_descripteur_fichier *)
872: (*((struct_liste_chainee *)
873: element_candidat)).donnee)).type == 'C')
874: {
875: if ((*((struct_descripteur_fichier *)
876: (*((struct_liste_chainee *)
877: element_courant)).donnee))
878: .descripteur_c ==
879: (*((struct_descripteur_fichier *)
880: (*((struct_liste_chainee *)
881: element_candidat)).donnee))
882: .descripteur_c)
883: {
884: break;
885: }
886: }
887: else
888: {
889: if (((*((struct_descripteur_fichier *)
890: (*((struct_liste_chainee *)
891: element_courant)).donnee))
892: .descripteur_sqlite ==
893: (*((struct_descripteur_fichier *)
894: (*((struct_liste_chainee *)
895: element_candidat)).donnee))
896: .descripteur_sqlite) &&
897: ((*((struct_descripteur_fichier *)
898: (*((struct_liste_chainee *)
899: element_courant)).donnee))
900: .descripteur_c ==
901: (*((struct_descripteur_fichier *)
902: (*((struct_liste_chainee *)
903: element_candidat)).donnee))
904: .descripteur_c))
905: {
906: break;
907: }
908: }
909: }
910: }
911:
912: element_candidat = (*((struct_liste_chainee *)
913: element_candidat)).suivant;
914: }
915:
916: if (element_candidat == NULL)
917: {
918: fclose((*((struct_descripteur_fichier *)
919: (*((struct_liste_chainee *) element_courant))
920: .donnee)).descripteur_c);
921:
922: if ((*((struct_descripteur_fichier *)
923: (*((struct_liste_chainee *) element_courant))
924: .donnee)).type != 'C')
925: {
926: sqlite3_close((*((struct_descripteur_fichier *)
927: (*((struct_liste_chainee *) element_courant))
928: .donnee)).descripteur_sqlite);
929: }
930: }
931:
932: free((*((struct_descripteur_fichier *)
933: (*((struct_liste_chainee *)
934: element_courant)).donnee)).nom);
935: free((struct_descripteur_fichier *)
936: (*((struct_liste_chainee *)
937: element_courant)).donnee);
938: free(element_courant);
939:
940: element_courant = element_suivant;
941: }
942:
943: element_courant = (*s_etat_processus).s_sockets;
944: while(element_courant != NULL)
945: {
946: element_suivant = (*((struct_liste_chainee *)
947: element_courant)).suivant;
948:
949: element_candidat = (*candidat).s_sockets;
950: while(element_candidat != NULL)
951: {
952: if (((*((struct_socket *)
953: (*((struct_liste_chainee *) element_courant))
954: .donnee)).socket == (*((struct_socket *)
955: (*((struct_liste_chainee *) element_candidat))
956: .donnee)).socket) &&
957: ((*((struct_socket *)
958: (*((struct_liste_chainee *) element_courant))
959: .donnee)).pid == (*((struct_socket *)
960: (*((struct_liste_chainee *) element_candidat))
961: .donnee)).pid) && (pthread_equal(
962: (*((struct_socket *)
963: (*((struct_liste_chainee *) element_courant))
964: .donnee)).tid, (*((struct_socket *)
965: (*((struct_liste_chainee *) element_candidat))
966: .donnee)).tid) != 0))
967: {
968: break;
969: }
970:
971: element_candidat = (*((struct_liste_chainee *)
972: element_candidat)).suivant;
973: }
974:
975: if (element_candidat == NULL)
976: {
977: if ((*((struct_socket *) (*((struct_liste_chainee *)
978: element_courant)).donnee)).socket_connectee
979: == d_vrai)
980: {
981: shutdown((*((struct_socket *)
982: (*((struct_liste_chainee *) element_courant))
983: .donnee)).socket, SHUT_RDWR);
984: }
985:
986: close((*((struct_socket *)
987: (*((struct_liste_chainee *) element_courant))
988: .donnee)).socket);
989: }
990:
991: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
992: element_courant)).donnee).mutex));
993: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
994: element_courant)).donnee).mutex));
995:
996: liberation(s_etat_processus,
997: (*((struct_liste_chainee *)
998: element_courant)).donnee);
999: free(element_courant);
1000:
1001: element_courant = element_suivant;
1002: }
1003:
1004: /*
1005: ================================================================================
1006: À noter : on ne ferme pas la connexion car la conséquence immédiate est
1007: une destruction de l'objet pour le processus père.
1008: ================================================================================
1009:
1010: element_courant = (*s_etat_processus).s_connecteurs_sql;
1011: while(element_courant != NULL)
1012: {
1013: element_suivant = (*((struct_liste_chainee *)
1014: element_courant)).suivant;
1015:
1016: element_candidat = (*candidat).s_connecteurs_sql;
1017: while(element_candidat != NULL)
1018: {
1019: if (((
1020: #ifdef MYSQL_SUPPORT
1021: ((*((struct_connecteur_sql *)
1022: (*((struct_liste_chainee *) element_courant))
1023: .donnee)).descripteur.mysql ==
1024: (*((struct_connecteur_sql *)
1025: (*((struct_liste_chainee *) element_candidat))
1026: .donnee)).descripteur.mysql)
1027: &&
1028: (strcmp((*((struct_connecteur_sql *)
1029: (*((struct_liste_chainee *) element_courant))
1030: .donnee)).type, "MYSQL") == 0)
1031: &&
1032: (strcmp((*((struct_connecteur_sql *)
1033: (*((struct_liste_chainee *) element_candidat))
1034: .donnee)).type, "MYSQL") == 0)
1035: #else
1036: 0
1037: #endif
1038: ) || (
1039: #ifdef POSTGRESQL_SUPPORT
1040: ((*((struct_connecteur_sql *)
1041: (*((struct_liste_chainee *) element_courant))
1042: .donnee)).descripteur.postgresql ==
1043: (*((struct_connecteur_sql *)
1044: (*((struct_liste_chainee *) element_candidat))
1045: .donnee)).descripteur.postgresql)
1046: &&
1047: (strcmp((*((struct_connecteur_sql *)
1048: (*((struct_liste_chainee *) element_courant))
1049: .donnee)).type, "POSTGRESQL") == 0)
1050: &&
1051: (strcmp((*((struct_connecteur_sql *)
1052: (*((struct_liste_chainee *) element_candidat))
1053: .donnee)).type, "POSTGRESQL") == 0)
1054: #else
1055: 0
1056: #endif
1057: )) &&
1058: ((*((struct_connecteur_sql *)
1059: (*((struct_liste_chainee *) element_courant))
1060: .donnee)).pid == (*((struct_connecteur_sql *)
1061: (*((struct_liste_chainee *) element_candidat))
1062: .donnee)).pid) && (pthread_equal(
1063: (*((struct_connecteur_sql *)
1064: (*((struct_liste_chainee *) element_courant))
1065: .donnee)).tid, (*((struct_connecteur_sql *)
1066: (*((struct_liste_chainee *) element_candidat))
1067: .donnee)).tid) != 0))
1068: {
1069: break;
1070: }
1071:
1072: element_candidat = (*((struct_liste_chainee *)
1073: element_candidat)).suivant;
1074: }
1075:
1076: if (element_candidat == NULL)
1077: {
1078: sqlclose((*((struct_liste_chainee *) element_courant))
1079: .donnee);
1080: }
1081:
1082: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1083: element_courant)).donnee).mutex));
1084: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1085: element_courant)).donnee).mutex));
1086:
1087: liberation(s_etat_processus, (*((struct_liste_chainee *)
1088: element_courant)).donnee);
1089: free(element_courant);
1090:
1091: element_courant = element_suivant;
1092: }
1093: */
1094:
1095: (*s_etat_processus).s_connecteurs_sql = NULL;
1096:
1097: element_courant = (*s_etat_processus).s_marques;
1098: while(element_courant != NULL)
1099: {
1100: free((*((struct_marque *) element_courant)).label);
1101: free((*((struct_marque *) element_courant)).position);
1102: element_suivant = (*((struct_marque *) element_courant))
1103: .suivant;
1104: free(element_courant);
1105: element_courant = element_suivant;
1106: }
1107:
1108: liberation_allocateur(s_etat_processus);
1109:
1110: pthread_mutex_unlock(&((*s_etat_processus).mutex_fork));
1111: pthread_mutex_destroy(&((*s_etat_processus).mutex_fork));
1112:
1113: liberation_contexte_cas(s_etat_processus);
1114: free(s_etat_processus);
1115:
1116: s_etat_processus = candidat;
1117: }
1118:
1119: l_element_suivant = (*l_element_courant).suivant;
1120:
1121: free((struct_thread *) (*l_element_courant).donnee);
1122: free((struct_liste_chainee *) l_element_courant);
1123:
1124: l_element_courant = l_element_suivant;
1125: }
1126:
1127: liste_threads = NULL;
1128:
1129: l_element_courant = liste_threads_surveillance;
1130:
1131: while(l_element_courant != NULL)
1132: {
1133: s_argument_thread = (struct_descripteur_thread *)
1134: (*l_element_courant).donnee;
1135:
1136: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
1137: != 0)
1138: {
1139: (*s_etat_processus).erreur_systeme = d_es_processus;
1140: pthread_mutex_unlock(&mutex_liste_threads);
1141: return;
1142: }
1143:
1144: (*s_argument_thread).nombre_references--;
1145:
1146: BUG((*s_argument_thread).nombre_references < 0,
1147: printf("(*s_argument_thread).nombre_references = %d\n",
1148: (int) (*s_argument_thread).nombre_references));
1149:
1150: if ((*s_argument_thread).nombre_references == 0)
1151: {
1152: close((*s_argument_thread).pipe_objets[0]);
1153: close((*s_argument_thread).pipe_acquittement[1]);
1154: close((*s_argument_thread).pipe_injections[1]);
1155: close((*s_argument_thread).pipe_nombre_injections[1]);
1156: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
1157: close((*s_argument_thread).pipe_interruptions[0]);
1158: close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
1159:
1160: if (pthread_mutex_unlock(&((*s_argument_thread)
1161: .mutex_nombre_references)) != 0)
1162: {
1163: (*s_etat_processus).erreur_systeme = d_es_processus;
1164: pthread_mutex_unlock(&mutex_liste_threads);
1165: return;
1166: }
1167:
1168: pthread_mutex_destroy(&((*s_argument_thread).mutex));
1169: pthread_mutex_destroy(&((*s_argument_thread)
1170: .mutex_nombre_references));
1171:
1172: if ((*s_argument_thread).processus_detache == d_faux)
1173: {
1174: if ((*s_argument_thread).destruction_objet == d_vrai)
1175: {
1176: liberation(s_etat_processus, (*s_argument_thread).argument);
1177: }
1178: }
1179:
1180: free(s_argument_thread);
1181: }
1182: else
1183: {
1184: if (pthread_mutex_unlock(&((*s_argument_thread)
1185: .mutex_nombre_references)) != 0)
1186: {
1187: (*s_etat_processus).erreur_systeme = d_es_processus;
1188: pthread_mutex_unlock(&mutex_liste_threads);
1189: return;
1190: }
1191: }
1192:
1193: l_element_suivant = (*l_element_courant).suivant;
1194: free((struct_liste_chainee *) l_element_courant);
1195: l_element_courant = l_element_suivant;
1196: }
1197:
1198: liste_threads_surveillance = NULL;
1199:
1200: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1201: {
1202: (*s_etat_processus).erreur_systeme = d_es_processus;
1203: return;
1204: }
1205:
1206: return;
1207: }
1208:
1209: static struct_processus *
1210: recherche_thread(pid_t pid, pthread_t tid)
1211: {
1212: volatile struct_liste_chainee_volatile *l_element_courant;
1213:
1214: struct_processus *s_etat_processus;
1215:
1216: l_element_courant = liste_threads;
1217:
1218: while(l_element_courant != NULL)
1219: {
1220: if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
1221: .tid, tid) != 0) && ((*((struct_thread *)
1222: (*l_element_courant).donnee)).pid == pid))
1223: {
1224: break;
1225: }
1226:
1227: l_element_courant = (*l_element_courant).suivant;
1228: }
1229:
1230: if (l_element_courant == NULL)
1231: {
1232: /*
1233: * Le processus n'existe plus. On ne distribue aucun signal.
1234: */
1235:
1236: return(NULL);
1237: }
1238:
1239: s_etat_processus = (*((struct_thread *)
1240: (*l_element_courant).donnee)).s_etat_processus;
1241:
1242: return(s_etat_processus);
1243: }
1244:
1245: static struct_processus *
1246: recherche_thread_principal(pid_t pid)
1247: {
1248: volatile struct_liste_chainee_volatile *l_element_courant;
1249:
1250: l_element_courant = liste_threads;
1251:
1252: while(l_element_courant != NULL)
1253: {
1254: if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
1255: == d_vrai) && ((*((struct_thread *)
1256: (*l_element_courant).donnee)).pid == pid))
1257: {
1258: break;
1259: }
1260:
1261: l_element_courant = (*l_element_courant).suivant;
1262: }
1263:
1264: if (l_element_courant == NULL)
1265: {
1266: /*
1267: * Le processus n'existe plus. On ne distribue aucun signal.
1268: */
1269:
1270: return(NULL);
1271: }
1272:
1273: return((*((struct_thread *) (*l_element_courant).donnee))
1274: .s_etat_processus);
1275: }
1276:
1277:
1278: /*
1279: ================================================================================
1280: Procédures de gestion des signaux d'interruption
1281: ================================================================================
1282: Entrée : variable globale
1283: --------------------------------------------------------------------------------
1284: Sortie : variable globale modifiée
1285: --------------------------------------------------------------------------------
1286: Effets de bord : néant
1287: ================================================================================
1288: */
1289:
1290: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
1291: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
1292: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
1293:
1294: static inline void
1295: verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
1296: {
1297: int semaphore;
1298:
1299: if (pthread_mutex_unlock(&((*s_etat_processus).mutex_fork)) != 0)
1300: {
1301: BUG(1, uprintf("Lock error !\n"));
1302: return;
1303: }
1304:
1305: // Il faut respecteur l'atomicité des deux opérations suivantes !
1306:
1307: if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) != 0)
1308: {
1309: pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1310: BUG(1, uprintf("Unlock error !\n"));
1311: return;
1312: }
1313:
1314: # ifndef SEMAPHORES_NOMMES
1315: if (sem_post(&semaphore_gestionnaires_signaux) == -1)
1316: # else
1317: if (sem_post(semaphore_gestionnaires_signaux) == -1)
1318: # endif
1319: {
1320: pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1321: BUG(1, uprintf("Lock error !\n"));
1322: return;
1323: }
1324:
1325: # ifndef SEMAPHORES_NOMMES
1326: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1327: # else
1328: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1329: # endif
1330: {
1331: pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1332: BUG(1, uprintf("Lock error !\n"));
1333: return;
1334: }
1335:
1336: if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
1337: {
1338: pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1339: BUG(1, uprintf("Unlock error !\n"));
1340: return;
1341: }
1342:
1343: if (semaphore == 1)
1344: {
1345: // Le semaphore ne peut être pris par le thread qui a appelé
1346: // le gestionnaire de signal car le signal est bloqué par ce thread
1347: // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
1348: // par un thread concurrent. On essaye donc de le bloquer jusqu'à
1349: // ce que ce soit possible.
1350:
1351: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1352: {
1353: pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1354: BUG(1, uprintf("Lock error !\n"));
1355: return;
1356: }
1357: }
1358:
1359: return;
1360: }
1361:
1362: static inline void
1363: deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
1364: {
1365: int semaphore;
1366:
1367: // Il faut respecteur l'atomicité des deux opérations suivantes !
1368:
1369: if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) == -1)
1370: {
1371: pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1372: BUG(1, uprintf("Unlock error !\n"));
1373: return;
1374: }
1375:
1376: # ifndef SEMAPHORES_NOMMES
1377: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1378: # else
1379: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1380: # endif
1381: {
1382: pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1383: BUG(1, uprintf("Unlock error !\n"));
1384: return;
1385: }
1386:
1387: # ifndef SEMAPHORES_NOMMES
1388: while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1389: # else
1390: while(sem_wait(semaphore_gestionnaires_signaux) == -1)
1391: # endif
1392: {
1393: if (errno != EINTR)
1394: {
1395: pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1396: BUG(1, uprintf("Unlock error !\n"));
1397: return;
1398: }
1399: }
1400:
1401: if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
1402: {
1403: pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1404: BUG(1, uprintf("Unlock error !\n"));
1405: return;
1406: }
1407:
1408: if (pthread_mutex_lock(&((*s_etat_processus).mutex_fork)) != 0)
1409: {
1410: BUG(1, uprintf("Unlock error !\n"));
1411: return;
1412: }
1413:
1414: if (semaphore == 1)
1415: {
1416: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1417: {
1418: BUG(1, uprintf("Unlock error !\n"));
1419: return;
1420: }
1421: }
1422:
1423: return;
1424: }
1425:
1426: #define test_signal(signal) \
1427: if (signal_test == SIGTEST) { signal_test = signal; return; }
1428:
1429: // Récupération des signaux
1430: // - SIGINT (arrêt au clavier)
1431: // - SIGTERM (signal d'arrêt en provenance du système)
1432:
1433: void
1434: interruption1(int signal)
1435: {
1436: test_signal(signal);
1437:
1438: switch(signal)
1439: {
1440: case SIGINT:
1441: envoi_signal_processus(getpid(), rpl_sigint);
1442: break;
1443:
1444: case SIGTERM:
1445: envoi_signal_processus(getpid(), rpl_sigterm);
1446: break;
1447:
1448: case SIGALRM:
1449: envoi_signal_processus(getpid(), rpl_sigalrm);
1450: break;
1451: }
1452:
1453: return;
1454: }
1455:
1456: inline static void
1457: signal_alrm(struct_processus *s_etat_processus, pid_t pid)
1458: {
1459: struct_processus *s_thread_principal;
1460:
1461: verrouillage_gestionnaire_signaux(s_etat_processus);
1462:
1463: if (pid == getpid())
1464: {
1465: // Si pid est égal à getpid(), le signal à traiter est issu
1466: // du même processus que celui qui va le traiter, mais d'un thread
1467: // différent.
1468:
1469: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1470: {
1471: printf("[%d] RPL/SIGALRM (thread %llu)\n", (int) getpid(),
1472: (unsigned long long) pthread_self());
1473: fflush(stdout);
1474: }
1475:
1476: if ((*s_etat_processus).pid_processus_pere != getpid())
1477: {
1478: // On n'est pas dans le processus père, on remonte le signal.
1479: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1480: rpl_sigalrm);
1481: }
1482: else
1483: {
1484: // On est dans le processus père, on effectue un arrêt d'urgence.
1485: (*s_etat_processus).var_volatile_alarme = -1;
1486: (*s_etat_processus).var_volatile_requete_arret = -1;
1487: }
1488: }
1489: else
1490: {
1491: // Le signal est issu d'un processus différent. On recherche le
1492: // thread principal pour remonter le signal.
1493:
1494: if ((s_thread_principal = recherche_thread_principal(getpid()))
1495: != NULL)
1496: {
1497: envoi_signal_contexte(s_thread_principal, rpl_sigalrm);
1498: }
1499: }
1500:
1501: deverrouillage_gestionnaire_signaux(s_etat_processus);
1502: return;
1503: }
1504:
1505: inline static void
1506: signal_term(struct_processus *s_etat_processus, pid_t pid)
1507: {
1508: struct_processus *s_thread_principal;
1509: volatile sig_atomic_t exclusion = 0;
1510:
1511: verrouillage_gestionnaire_signaux(s_etat_processus);
1512:
1513: if (pid == getpid())
1514: {
1515: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1516: {
1517: printf("[%d] RPL/SIGTERM (thread %llu)\n", (int) getpid(),
1518: (unsigned long long) pthread_self());
1519: fflush(stdout);
1520: }
1521:
1522: if ((*s_etat_processus).pid_processus_pere != getpid())
1523: {
1524: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1525: rpl_sigterm);
1526: }
1527: else
1528: {
1529: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1530:
1531: while(exclusion == 1);
1532: exclusion = 1;
1533:
1534: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1535: {
1536: deverrouillage_gestionnaire_signaux(s_etat_processus);
1537: exclusion = 0;
1538: return;
1539: }
1540:
1541: (*s_etat_processus).var_volatile_requete_arret = -1;
1542: (*s_etat_processus).var_volatile_alarme = -1;
1543:
1544: exclusion = 0;
1545: }
1546: }
1547: else
1548: {
1549: if ((s_thread_principal = recherche_thread_principal(getpid()))
1550: != NULL)
1551: {
1552: envoi_signal_contexte(s_thread_principal, rpl_sigterm);
1553: }
1554: }
1555:
1556: deverrouillage_gestionnaire_signaux(s_etat_processus);
1557: return;
1558: }
1559:
1560: inline static void
1561: signal_int(struct_processus *s_etat_processus, pid_t pid)
1562: {
1563: struct_processus *s_thread_principal;
1564: volatile sig_atomic_t exclusion = 0;
1565:
1566: verrouillage_gestionnaire_signaux(s_etat_processus);
1567:
1568: if (pid == getpid())
1569: {
1570: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1571: {
1572: printf("[%d] RPL/SIGINT (thread %llu)\n", (int) getpid(),
1573: (unsigned long long) pthread_self());
1574: fflush(stdout);
1575: }
1576:
1577: if ((*s_etat_processus).pid_processus_pere != getpid())
1578: {
1579: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1580: rpl_sigint);
1581: }
1582: else
1583: {
1584: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1585:
1586: while(exclusion == 1);
1587: exclusion = 1;
1588:
1589: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1590: {
1591: deverrouillage_gestionnaire_signaux(s_etat_processus);
1592: exclusion = 0;
1593: return;
1594: }
1595:
1596: if ((*s_etat_processus).langue == 'F')
1597: {
1598: printf("+++Interruption\n");
1599: }
1600: else
1601: {
1602: printf("+++Interrupt\n");
1603: }
1604:
1605: fflush(stdout);
1606:
1607: (*s_etat_processus).var_volatile_requete_arret = -1;
1608: (*s_etat_processus).var_volatile_alarme = -1;
1609:
1610: exclusion = 0;
1611: }
1612: }
1613: else
1614: {
1615: if ((s_thread_principal = recherche_thread_principal(getpid()))
1616: != NULL)
1617: {
1618: envoi_signal_contexte(s_thread_principal, rpl_sigint);
1619: }
1620: }
1621:
1622: deverrouillage_gestionnaire_signaux(s_etat_processus);
1623: return;
1624: }
1625:
1626: // Récupération des signaux
1627: // - SIGFSTP
1628: //
1629: // ATTENTION :
1630: // Le signal SIGFSTP provient de la mort du processus de contrôle.
1631: // Sous certains systèmes (Linux...), la mort du terminal de contrôle
1632: // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
1633: // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
1634: // non initialisée (pointeur NULL) issue de TERMIO.
1635:
1636: void
1637: interruption2(int signal)
1638: {
1639: test_signal(signal);
1640: envoi_signal_processus(getpid(), rpl_sigtstp);
1641: return;
1642: }
1643:
1644: static inline void
1645: signal_tstp(struct_processus *s_etat_processus, pid_t pid)
1646: {
1647: struct_processus *s_thread_principal;
1648:
1649: verrouillage_gestionnaire_signaux(s_etat_processus);
1650:
1651: if (pid == getpid())
1652: {
1653: /*
1654: * 0 => fonctionnement normal
1655: * -1 => requête
1656: * 1 => requête acceptée en attente de traitement
1657: */
1658:
1659: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1660: {
1661: printf("[%d] RPL/SIGTSTP (thread %llu)\n", (int) getpid(),
1662: (unsigned long long) pthread_self());
1663: fflush(stdout);
1664: }
1665:
1666: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1667: {
1668: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1669: rpl_sigtstp);
1670: }
1671: else
1672: {
1673: (*s_etat_processus).var_volatile_requete_arret2 = -1;
1674: }
1675: }
1676: else
1677: {
1678: // Envoi d'un signal au thread maître du groupe.
1679:
1680: if ((s_thread_principal = recherche_thread_principal(getpid()))
1681: != NULL)
1682: {
1683: envoi_signal_contexte(s_thread_principal, rpl_sigtstp);
1684: }
1685: }
1686:
1687: deverrouillage_gestionnaire_signaux(s_etat_processus);
1688: return;
1689: }
1690:
1691: void
1692: interruption3(int signal)
1693: {
1694: // Si on passe par ici, c'est qu'il est impossible de récupérer
1695: // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
1696: // ce qu'il reste des processus orphelins.
1697:
1698: unsigned char message[] = "+++System : Uncaught access violation\n"
1699: "+++System : Aborting !\n";
1700:
1701: test_signal(signal);
1702:
1703: if (pid_processus_pere == getpid())
1704: {
1705: kill(pid_processus_pere, SIGALRM);
1706: }
1707:
1708: write(STDERR_FILENO, message, strlen(message));
1709: _exit(EXIT_FAILURE);
1710: }
1711:
1712: #if 0
1713: // Utiliser libsigsegv
1714: void INTERRUPTION3_A_FIXER()
1715: {
1716: pthread_t thread;
1717:
1718: struct_processus *s_etat_processus;
1719:
1720: test_signal(signal);
1721: verrouillage_gestionnaire_signaux(s_etat_processus);
1722:
1723: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1724: {
1725: deverrouillage_gestionnaire_signaux(s_etat_processus);
1726: return;
1727: }
1728:
1729: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1730: {
1731: printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
1732: (unsigned long long) pthread_self());
1733: fflush(stdout);
1734: }
1735:
1736: if ((*s_etat_processus).var_volatile_recursivite == -1)
1737: {
1738: // Segfault dans un appel de fonction récursive
1739: deverrouillage_gestionnaire_signaux(s_etat_processus);
1740: longjmp(contexte, -1);
1741: }
1742: else
1743: {
1744: // Segfault dans une routine interne
1745: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1746: {
1747: printf("+++Système : Violation d'accès\n");
1748: }
1749: else
1750: {
1751: printf("+++System : Access violation\n");
1752: }
1753:
1754: fflush(stdout);
1755:
1756: (*s_etat_processus).compteur_violation_d_acces++;
1757:
1758: if ((*s_etat_processus).compteur_violation_d_acces > 1)
1759: {
1760: // On vient de récupérer plus d'une erreur de segmentation
1761: // dans le même processus ou le même thread. L'erreur n'est pas
1762: // récupérable et on sort autoritairement du programme. Il peut
1763: // rester des processus orphelins en attente !
1764:
1765: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1766: {
1767: printf("+++Système : Violation d'accès, tentative de "
1768: "terminaison de la tâche\n");
1769: printf(" (defauts multiples)\n");
1770: }
1771: else
1772: {
1773: printf("+++System : Access violation, trying to kill task "
1774: "(multiple defaults)\n");
1775: }
1776:
1777: fflush(stdout);
1778:
1779: deverrouillage_gestionnaire_signaux(s_etat_processus);
1780: exit(EXIT_FAILURE);
1781: }
1782: else
1783: {
1784: // Première erreur de segmentation. On essaie de terminer
1785: // proprement le thread ou le processus. Le signal ne peut être
1786: // envoyé que depuis le même processus.
1787:
1788: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1789: {
1790: if (pthread_equal(thread, pthread_self()) != 0)
1791: {
1792: deverrouillage_gestionnaire_signaux(s_etat_processus);
1793:
1794: if ((*s_etat_processus).pid_processus_pere != getpid())
1795: {
1796: // On est dans le thread principal d'un processus.
1797:
1798: longjmp(contexte_processus, -1);
1799: }
1800: else
1801: {
1802: // On est dans le thread principal du processus
1803: // père.
1804:
1805: longjmp(contexte_initial, -1);
1806: }
1807: }
1808: else
1809: {
1810: // On est dans un thread fils d'un thread principal.
1811:
1812: deverrouillage_gestionnaire_signaux(s_etat_processus);
1813: longjmp(contexte_thread, -1);
1814: }
1815: }
1816:
1817: // Là, on ramasse les miettes puisque le thread n'existe plus
1818: // dans la base (corruption de la mémoire).
1819:
1820: deverrouillage_gestionnaire_signaux(s_etat_processus);
1821: longjmp(contexte_initial, -1);
1822: }
1823: }
1824:
1825: deverrouillage_gestionnaire_signaux(s_etat_processus);
1826: return;
1827: }
1828: #endif
1829:
1830: // Traitement de rpl_sigstart
1831:
1832: static inline void
1833: signal_start(struct_processus *s_etat_processus, pid_t pid)
1834: {
1835: (*s_etat_processus).demarrage_fils = d_vrai;
1836: return;
1837: }
1838:
1839: // Traitement de rpl_sigcont
1840:
1841: static inline void
1842: signal_cont(struct_processus *s_etat_processus, pid_t pid)
1843: {
1844: (*s_etat_processus).redemarrage_processus = d_vrai;
1845: return;
1846: }
1847:
1848: // Traitement de rpl_sigstop
1849:
1850: static inline void
1851: signal_stop(struct_processus *s_etat_processus, pid_t pid)
1852: {
1853: struct_processus *s_thread_principal;
1854:
1855: verrouillage_gestionnaire_signaux(s_etat_processus);
1856:
1857: if (pid == getpid())
1858: {
1859: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1860: == NULL)
1861: {
1862: deverrouillage_gestionnaire_signaux(s_etat_processus);
1863: return;
1864: }
1865:
1866: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1867: {
1868: printf("[%d] RPL/SIGFSTOP (thread %llu)\n", (int) getpid(),
1869: (unsigned long long) pthread_self());
1870: fflush(stdout);
1871: }
1872:
1873: /*
1874: * var_globale_traitement_retarde_stop :
1875: * 0 -> traitement immédiat
1876: * 1 -> traitement retardé (aucun signal reçu)
1877: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
1878: */
1879:
1880: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
1881: {
1882: (*s_etat_processus).var_volatile_requete_arret = -1;
1883: }
1884: else
1885: {
1886: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
1887: }
1888: }
1889: else
1890: {
1891: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1892: == NULL)
1893: {
1894: deverrouillage_gestionnaire_signaux(s_etat_processus);
1895: return;
1896: }
1897:
1898: // Envoi d'un signal au thread maître du groupe.
1899:
1900: if ((s_thread_principal = recherche_thread_principal(getpid()))
1901: != NULL)
1902: {
1903: envoi_signal_contexte(s_thread_principal, rpl_sigstop);
1904: }
1905: }
1906:
1907: deverrouillage_gestionnaire_signaux(s_etat_processus);
1908: return;
1909: }
1910:
1911: // Traitement de rpl_siginject
1912:
1913: static inline void
1914: signal_inject(struct_processus *s_etat_processus, pid_t pid)
1915: {
1916: verrouillage_gestionnaire_signaux(s_etat_processus);
1917:
1918: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1919: {
1920: deverrouillage_gestionnaire_signaux(s_etat_processus);
1921: return;
1922: }
1923:
1924: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1925: {
1926: printf("[%d] RPL/SIGINJECT (thread %llu)\n", (int) getpid(),
1927: (unsigned long long) pthread_self());
1928: fflush(stdout);
1929: }
1930:
1931: deverrouillage_gestionnaire_signaux(s_etat_processus);
1932: return;
1933: }
1934:
1935: // Récupération des signaux
1936: // - SIGPIPE
1937:
1938: void
1939: interruption5(int signal)
1940: {
1941: unsigned char message[] = "+++System : SIGPIPE\n"
1942: "+++System : Aborting !\n";
1943:
1944: test_signal(signal);
1945:
1946: if (pid_processus_pere == getpid())
1947: {
1948: envoi_signal_processus(pid_processus_pere, rpl_sigalrm);
1949: }
1950:
1951: write(STDERR_FILENO, message, strlen(message));
1952: return;
1953: }
1954:
1955: static inline void
1956: signal_urg(struct_processus *s_etat_processus, pid_t pid)
1957: {
1958: struct_processus *s_thread_principal;
1959:
1960: verrouillage_gestionnaire_signaux(s_etat_processus);
1961:
1962: if (pid == getpid())
1963: {
1964: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1965: == NULL)
1966: {
1967: deverrouillage_gestionnaire_signaux(s_etat_processus);
1968: return;
1969: }
1970:
1971: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1972: {
1973: printf("[%d] RPL/SIGURG (thread %llu)\n", (int) getpid(),
1974: (unsigned long long) pthread_self());
1975: fflush(stdout);
1976: }
1977:
1978: (*s_etat_processus).var_volatile_alarme = -1;
1979: (*s_etat_processus).var_volatile_requete_arret = -1;
1980: }
1981: else
1982: {
1983: // Envoi d'un signal au thread maître du groupe.
1984:
1985: if ((s_thread_principal = recherche_thread_principal(getpid()))
1986: != NULL)
1987: {
1988: envoi_signal_contexte(s_thread_principal, rpl_sigurg);
1989: }
1990: }
1991:
1992: deverrouillage_gestionnaire_signaux(s_etat_processus);
1993: return;
1994: }
1995:
1996: // Traitement de rpl_sigabort
1997:
1998: static inline void
1999: signal_abort(struct_processus *s_etat_processus, pid_t pid)
2000: {
2001: struct_processus *s_thread_principal;
2002:
2003: verrouillage_gestionnaire_signaux(s_etat_processus);
2004:
2005: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2006: {
2007: deverrouillage_gestionnaire_signaux(s_etat_processus);
2008: return;
2009: }
2010:
2011: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2012: {
2013: printf("[%d] RPL/SIGABORT (thread %llu)\n", (int) getpid(),
2014: (unsigned long long) pthread_self());
2015: fflush(stdout);
2016: }
2017:
2018: if (pid == getpid())
2019: {
2020: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2021: == NULL)
2022: {
2023: deverrouillage_gestionnaire_signaux(s_etat_processus);
2024: return;
2025: }
2026:
2027: (*s_etat_processus).arret_depuis_abort = -1;
2028:
2029: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2030: {
2031: printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
2032: (unsigned long long) pthread_self());
2033: fflush(stdout);
2034: }
2035:
2036: /*
2037: * var_globale_traitement_retarde_stop :
2038: * 0 -> traitement immédiat
2039: * 1 -> traitement retardé (aucun signal reçu)
2040: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2041: */
2042:
2043: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2044: {
2045: (*s_etat_processus).var_volatile_requete_arret = -1;
2046: }
2047: else
2048: {
2049: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2050: }
2051: }
2052: else
2053: {
2054: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2055: == NULL)
2056: {
2057: deverrouillage_gestionnaire_signaux(s_etat_processus);
2058: return;
2059: }
2060:
2061: (*s_etat_processus).arret_depuis_abort = -1;
2062:
2063: // Envoi d'un signal au thread maître du groupe.
2064:
2065: if ((s_thread_principal = recherche_thread_principal(getpid()))
2066: != NULL)
2067: {
2068: envoi_signal_contexte(s_thread_principal, rpl_sigabort);
2069: }
2070: }
2071:
2072: deverrouillage_gestionnaire_signaux(s_etat_processus);
2073: return;
2074: }
2075:
2076: // Récupération des signaux
2077: // - SIGHUP
2078:
2079: void
2080: interruption4(int signal)
2081: {
2082: test_signal(signal);
2083: envoi_signal_processus(getpid(), rpl_sighup);
2084: return;
2085: }
2086:
2087: static inline void
2088: signal_hup(struct_processus *s_etat_processus, pid_t pid)
2089: {
2090: file *fichier;
2091:
2092: unsigned char nom[8 + 64 + 1];
2093:
2094: verrouillage_gestionnaire_signaux(s_etat_processus);
2095:
2096: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2097: {
2098: deverrouillage_gestionnaire_signaux(s_etat_processus);
2099: return;
2100: }
2101:
2102: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
2103: (unsigned long) pthread_self());
2104:
2105: if ((fichier = fopen(nom, "w+")) != NULL)
2106: {
2107: fclose(fichier);
2108:
2109: freopen(nom, "w", stdout);
2110: freopen(nom, "w", stderr);
2111: }
2112:
2113: freopen("/dev/null", "r", stdin);
2114:
2115: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2116: {
2117: printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
2118: (unsigned long long) pthread_self());
2119: fflush(stdout);
2120: }
2121:
2122: deverrouillage_gestionnaire_signaux(s_etat_processus);
2123: return;
2124: }
2125:
2126: void
2127: traitement_exceptions_gsl(const char *reason, const char *file,
2128: int line, int gsl_errno)
2129: {
2130: code_erreur_gsl = gsl_errno;
2131: envoi_signal_processus(getpid(), rpl_sigexcept);
2132: return;
2133: }
2134:
2135: static inline void
2136: signal_except(struct_processus *s_etat_processus, pid_t pid)
2137: {
2138: verrouillage_gestionnaire_signaux(s_etat_processus);
2139:
2140: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2141: {
2142: deverrouillage_gestionnaire_signaux(s_etat_processus);
2143: return;
2144: }
2145:
2146: (*s_etat_processus).var_volatile_exception_gsl = code_erreur_gsl;
2147: deverrouillage_gestionnaire_signaux(s_etat_processus);
2148:
2149: return;
2150: }
2151:
2152: static inline void
2153: envoi_interruptions(struct_processus *s_etat_processus, enum signaux_rpl signal,
2154: pid_t pid_source)
2155: {
2156: unsigned char message[] = "+++System : Spurious signa !\n";
2157:
2158: switch(signal)
2159: {
2160: case rpl_sigint:
2161: signal_int(s_etat_processus, pid_source);
2162: break;
2163:
2164: case rpl_sigterm:
2165: signal_term(s_etat_processus, pid_source);
2166: break;
2167:
2168: case rpl_sigstart:
2169: signal_start(s_etat_processus, pid_source);
2170: break;
2171:
2172: case rpl_sigcont:
2173: signal_cont(s_etat_processus, pid_source);
2174: break;
2175:
2176: case rpl_sigstop:
2177: signal_stop(s_etat_processus, pid_source);
2178: break;
2179:
2180: case rpl_sigabort:
2181: signal_abort(s_etat_processus, pid_source);
2182: break;
2183:
2184: case rpl_sigurg:
2185: signal_urg(s_etat_processus, pid_source);
2186: break;
2187:
2188: case rpl_siginject:
2189: signal_inject(s_etat_processus, pid_source);
2190: break;
2191:
2192: case rpl_sigalrm:
2193: signal_alrm(s_etat_processus, pid_source);
2194: break;
2195:
2196: case rpl_sighup:
2197: signal_hup(s_etat_processus, pid_source);
2198: break;
2199:
2200: case rpl_sigtstp:
2201: signal_tstp(s_etat_processus, pid_source);
2202: break;
2203:
2204: case rpl_sigexcept:
2205: signal_except(s_etat_processus, pid_source);
2206: break;
2207:
2208: default:
2209: write(STDERR_FILENO, message, strlen(message));
2210: break;
2211: }
2212:
2213: return;
2214: }
2215:
2216: void
2217: scrutation_interruptions(struct_processus *s_etat_processus)
2218: {
2219: // Interruptions qui arrivent sur le processus depuis un
2220: // processus externe.
2221:
2222: // Les pointeurs de lecture pointent sur les prochains éléments
2223: // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à
2224: // écrire.
2225:
2226: if (pthread_mutex_trylock(&((*s_queue_signaux).mutex)) == 0)
2227: {
2228: if ((*s_queue_signaux).pointeur_lecture !=
2229: (*s_queue_signaux).pointeur_ecriture)
2230: {
2231: // Il y a un signal en attente dans le segment partagé. On le
2232: // traite.
2233:
2234: envoi_interruptions(s_etat_processus,
2235: (*s_queue_signaux).queue[(*s_queue_signaux)
2236: .pointeur_lecture].signal, (*s_queue_signaux).queue
2237: [(*s_queue_signaux).pointeur_lecture].pid);
2238: (*s_queue_signaux).pointeur_lecture =
2239: ((*s_queue_signaux).pointeur_lecture + 1)
2240: % LONGUEUR_QUEUE_SIGNAUX;
2241: }
2242:
2243: pthread_mutex_unlock(&((*s_queue_signaux).mutex));
2244: }
2245:
2246: // Interruptions qui arrivent depuis le groupe courant de threads.
2247:
2248: if (pthread_mutex_trylock(&mutex_interruptions) == 0)
2249: {
2250: if ((*s_etat_processus).pointeur_signal_lecture !=
2251: (*s_etat_processus).pointeur_signal_ecriture)
2252: {
2253: // Il y a un signal dans la queue du thread courant. On le traite.
2254:
2255: envoi_interruptions(s_etat_processus,
2256: (*s_etat_processus).signaux_en_queue
2257: [(*s_etat_processus).pointeur_signal_lecture],
2258: getpid());
2259: (*s_etat_processus).pointeur_signal_lecture =
2260: ((*s_etat_processus).pointeur_signal_lecture + 1)
2261: % LONGUEUR_QUEUE_SIGNAUX;
2262: }
2263:
2264: pthread_mutex_unlock(&mutex_interruptions);
2265: }
2266:
2267: return;
2268: }
2269:
2270: int
2271: envoi_signal_processus(pid_t pid, enum signaux_rpl signal)
2272: {
2273: // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en
2274: // mémoire puis d'y inscrire le signal à traiter.
2275:
2276: return(0);
2277: }
2278:
2279: int
2280: envoi_signal_thread(pthread_t tid, enum signaux_rpl signal)
2281: {
2282: // Un signal est envoyé d'un thread à un autre thread du même processus.
2283:
2284: volatile struct_liste_chainee_volatile *l_element_courant;
2285:
2286: struct_processus *s_etat_processus;
2287:
2288: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
2289: {
2290: return(1);
2291: }
2292:
2293: l_element_courant = liste_threads;
2294:
2295: while(l_element_courant != NULL)
2296: {
2297: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
2298: == getpid()) && (pthread_equal((*((struct_thread *)
2299: (*l_element_courant).donnee)).tid, tid) != 0))
2300: {
2301: break;
2302: }
2303:
2304: l_element_courant = (*l_element_courant).suivant;
2305: }
2306:
2307: if (l_element_courant == NULL)
2308: {
2309: pthread_mutex_unlock(&mutex_liste_threads);
2310: return(1);
2311: }
2312:
2313: if (pthread_mutex_lock(&mutex_interruptions) != 0)
2314: {
2315: pthread_mutex_unlock(&mutex_liste_threads);
2316: return(1);
2317: }
2318:
2319: s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))
2320: .s_etat_processus;
2321:
2322: (*s_etat_processus).signaux_en_queue
2323: [(*s_etat_processus).pointeur_signal_ecriture] = signal;
2324: (*s_etat_processus).pointeur_signal_ecriture =
2325: ((*s_etat_processus).pointeur_signal_ecriture + 1)
2326: % LONGUEUR_QUEUE_SIGNAUX;
2327:
2328: if (pthread_mutex_unlock(&mutex_interruptions) != 0)
2329: {
2330: pthread_mutex_unlock(&mutex_liste_threads);
2331: return(1);
2332: }
2333:
2334: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
2335: {
2336: return(1);
2337: }
2338:
2339: return(0);
2340: }
2341:
2342: int
2343: envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
2344: enum signaux_rpl signal)
2345: {
2346: pthread_mutex_lock(&mutex_interruptions);
2347: (*s_etat_processus_a_signaler).signaux_en_queue
2348: [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =
2349: signal;
2350: (*s_etat_processus_a_signaler).pointeur_signal_ecriture =
2351: ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)
2352: % LONGUEUR_QUEUE_SIGNAUX;
2353: pthread_mutex_unlock(&mutex_interruptions);
2354:
2355: return(0);
2356: }
2357:
2358:
2359: /*
2360: ================================================================================
2361: Fonction renvoyant le nom du segment de mémoire partagée en fonction
2362: du pid du processus.
2363: ================================================================================
2364: Entrée : Chemin absolue servant de racine, pid du processus
2365: --------------------------------------------------------------------------------
2366: Sortie : NULL ou nom du segment
2367: --------------------------------------------------------------------------------
2368: Effet de bord : Néant
2369: ================================================================================
2370: */
2371:
2372: static unsigned char *
2373: nom_segment(unsigned char *chemin, pid_t pid)
2374: {
2375: unsigned char *fichier;
2376:
2377: # ifdef IPCS_SYSV // !POSIX
2378: # ifndef OS2 // !OS2
2379:
2380: if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
2381: sizeof(unsigned char))) == NULL)
2382: {
2383: return(NULL);
2384: }
2385:
2386: sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
2387: # else // OS2
2388: if ((fichier = malloc((10 + 256 + 1) * sizeof(unsigned char)))
2389: == NULL)
2390: {
2391: return(NULL);
2392: }
2393:
2394: sprintf(fichier, "\\SHAREMEM\\RPL-SIGQUEUES-%d", (int) pid);
2395: # endif // OS2
2396: # else // POSIX
2397:
2398: if ((fichier = malloc((1 + 256 + 1) *
2399: sizeof(unsigned char))) == NULL)
2400: {
2401: return(NULL);
2402: }
2403:
2404: sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
2405: # endif
2406:
2407: return(fichier);
2408: }
2409:
2410:
2411: /*
2412: ================================================================================
2413: Fonction créant un segment de mémoire partagée destiné à contenir
2414: la queue des signaux.
2415: ================================================================================
2416: Entrée : structure de description du processus
2417: --------------------------------------------------------------------------------
2418: Sortie : Néant
2419: --------------------------------------------------------------------------------
2420: Effet de bord : Néant
2421: ================================================================================
2422: */
2423:
2424: void
2425: creation_queue_signaux(struct_processus *s_etat_processus)
2426: {
2427: int segment;
2428:
2429: pthread_mutexattr_t attributs_mutex;
2430:
2431: unsigned char *nom;
2432:
2433: # ifndef IPCS_SYSV // POSIX
2434:
2435: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
2436: getpid())) == NULL)
2437: {
2438: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2439: return;
2440: }
2441:
2442: if ((segment = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
2443: S_IRUSR | S_IWUSR)) == -1)
2444: {
2445: free(nom);
2446: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2447: return;
2448: }
2449:
2450: if (ftruncate(segment, sizeof(struct_queue_signaux)) == -1)
2451: {
2452: free(nom);
2453: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2454: return;
2455: }
2456:
2457: s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux),
2458: PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0);
2459: close(segment);
2460:
2461: if (((void *) s_queue_signaux) == ((void *) -1))
2462: {
2463: if (shm_unlink(nom) == -1)
2464: {
2465: free(nom);
2466: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2467: return;
2468: }
2469:
2470: free(nom);
2471: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2472: return;
2473: }
2474:
2475: free(nom);
2476:
2477: pthread_mutexattr_init(&attributs_mutex);
2478: pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL);
2479: pthread_mutex_init(&((*s_queue_signaux).mutex), &attributs_mutex);
2480: pthread_mutexattr_destroy(&attributs_mutex);
2481:
2482: (*s_queue_signaux).pointeur_lecture = 0;
2483: (*s_queue_signaux).pointeur_ecriture = 0;
2484:
2485: # else // SystemV
2486: # ifndef OS2
2487:
2488: file *desc;
2489:
2490: key_t clef;
2491:
2492: // Création d'un segment de données associé au PID du processus courant
2493:
2494: chemin = (*s_etat_processus).chemin_fichiers_temporaires;
2495:
2496: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
2497: getpid())) == NULL)
2498: {
2499: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2500: return;
2501: }
2502:
2503: if ((desc = fopen(nom, "w")) == NULL)
2504: {
2505: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
2506: return;
2507: }
2508:
2509: fclose(desc);
2510:
2511: if ((clef = ftok(nom, 1)) == -1)
2512: {
2513: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2514: return;
2515: }
2516:
2517: free(nom);
2518:
2519: if ((segment = shmget(clef,
2520: nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
2521: IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
2522: {
2523: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2524: return;
2525: }
2526:
2527: fifos = shmat(segment, NULL, 0);
2528:
2529: if (((void *) fifos) == ((void *) -1))
2530: {
2531: if (shmctl(segment, IPC_RMID, 0) == -1)
2532: {
2533: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2534: return;
2535: }
2536:
2537: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2538: return;
2539: }
2540:
2541: # else
2542:
2543: if ((nom = nom_segment(NULL, getpid())) == NULL)
2544: {
2545: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2546: return;
2547: }
2548:
2549: if (DosAllocSharedMem(&ptr_os2, nom, nombre_queues *
2550: ((2 * longueur_queue) + 4) * sizeof(int),
2551: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
2552: {
2553: free(nom);
2554: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2555: return;
2556: }
2557:
2558: free(nom);
2559: fifos = ptr_os2;
2560:
2561: # endif
2562: # endif
2563:
2564: return;
2565: }
2566:
2567:
2568: /*
2569: ================================================================================
2570: Fonction libérant le segment de mémoire partagée destiné à contenir
2571: la queue des signaux.
2572: ================================================================================
2573: Entrée : structure de description du processus
2574: --------------------------------------------------------------------------------
2575: Sortie : Néant
2576: --------------------------------------------------------------------------------
2577: Effet de bord : Néant
2578: ================================================================================
2579: */
2580:
2581: void
2582: liberation_queue_signaux(struct_processus *s_etat_processus)
2583: {
2584: # ifdef IPCS_SYSV // SystemV
2585: # ifndef OS2
2586: # else // OS/2
2587: # endif
2588: # else // POSIX
2589: if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
2590: {
2591: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2592: return;
2593: }
2594: # endif
2595:
2596: return;
2597: }
2598:
2599:
2600: /*
2601: ================================================================================
2602: Fonction détruisant le segment de mémoire partagée destiné à contenir
2603: la queue des signaux.
2604: ================================================================================
2605: Entrée : structure de description du processus
2606: --------------------------------------------------------------------------------
2607: Sortie : Néant
2608: --------------------------------------------------------------------------------
2609: Effet de bord : Néant
2610: ================================================================================
2611: */
2612:
2613: void
2614: destruction_queue_signaux(struct_processus *s_etat_processus)
2615: {
2616: unsigned char *nom;
2617:
2618: # ifdef IPCS_SYSV // SystemV
2619: # ifndef OS2
2620:
2621: if (shmdt(fifos) == -1)
2622: {
2623: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2624: return;
2625: }
2626:
2627: if (shmctl(segment, IPC_RMID, 0) == -1)
2628: {
2629: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2630: return;
2631: }
2632:
2633: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
2634: getpid())) == NULL)
2635: {
2636: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2637: return;
2638: }
2639:
2640: unlink(nom);
2641: free(nom);
2642:
2643: # else
2644:
2645: if (DosFreeMem(fifos) != 0)
2646: {
2647: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2648: return;
2649: }
2650:
2651: # endif
2652: # else // POSIX
2653:
2654: if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
2655: {
2656: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2657: return;
2658: }
2659:
2660: if ((nom = nom_segment(NULL, getpid())) == NULL)
2661: {
2662: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2663: return;
2664: }
2665:
2666: if (shm_unlink(nom) != 0)
2667: {
2668: free(nom);
2669: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2670: return;
2671: }
2672:
2673: free(nom);
2674:
2675: # endif
2676:
2677: return;
2678: }
2679:
2680: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>