![]() ![]() | ![]() |
1.1 bertrand 1: /*
2: ================================================================================
1.6 ! bertrand 3: RPL/2 (R) version 4.0.13
1.1 bertrand 4: Copyright (C) 1989-2010 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:
61: void
62: modification_pid_thread_pere(struct_processus *s_etat_processus)
63: {
64: // La variable existe toujours et aucun thread concurrent ne peut
65: // la modifier puisque cette routine ne peut être appelée que depuis
66: // DAEMON.
67:
68: (*((struct_thread *) (*liste_threads).donnee)).pid =
69: (*s_etat_processus).pid_processus_pere;
70:
71: return;
72: }
73:
74: void
75: insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)
76: {
77: sigset_t oldset;
78: sigset_t set;
79:
80: volatile struct_liste_chainee_volatile *l_nouvel_objet;
81:
82: sigfillset(&set);
83: pthread_sigmask(SIG_BLOCK, &set, &oldset);
84:
85: while(sem_wait(&semaphore_liste_threads) == -1)
86: {
87: if (errno != EINTR)
88: {
89: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
90: sigpending(&set);
91:
92: (*s_etat_processus).erreur_systeme = d_es_processus;
93: return;
94: }
95: }
96:
97: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
98: == NULL)
99: {
100: sem_post(&semaphore_liste_threads);
101: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
102: sigpending(&set);
103:
104: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
105: return;
106: }
107:
108: (*l_nouvel_objet).suivant = liste_threads;
109:
110: if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)
111: {
112: sem_post(&semaphore_liste_threads);
113: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
114: sigpending(&set);
115:
116: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
117: return;
118: }
119:
120: (*((struct_thread *) (*l_nouvel_objet).donnee)).pid = getpid();
121: (*((struct_thread *) (*l_nouvel_objet).donnee)).tid = pthread_self();
122: (*((struct_thread *) (*l_nouvel_objet).donnee)).thread_principal =
123: thread_principal;
124: (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
125: s_etat_processus;
126:
127: liste_threads = l_nouvel_objet;
128:
129: if (sem_post(&semaphore_liste_threads) != 0)
130: {
131: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
132: sigpending(&set);
133:
134: (*s_etat_processus).erreur_systeme = d_es_processus;
135: return;
136: }
137:
138: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
139: sigpending(&set);
140: return;
141: }
142:
143: void
144: insertion_thread_surveillance(struct_processus *s_etat_processus,
145: struct_descripteur_thread *s_argument_thread)
146: {
147: sigset_t oldset;
148: sigset_t set;
149:
150: volatile struct_liste_chainee_volatile *l_nouvel_objet;
151:
152: sigfillset(&set);
153: pthread_sigmask(SIG_BLOCK, &set, &oldset);
154:
155: while(sem_wait(&semaphore_liste_threads) == -1)
156: {
157: if (errno != EINTR)
158: {
159: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
160: sigpending(&set);
161:
162: (*s_etat_processus).erreur_systeme = d_es_processus;
163: return;
164: }
165: }
166:
167: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
168: == NULL)
169: {
170: sem_post(&semaphore_liste_threads);
171: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
172: sigpending(&set);
173:
174: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
175: return;
176: }
177:
178: (*l_nouvel_objet).suivant = liste_threads_surveillance;
179: (*l_nouvel_objet).donnee = (void *) s_argument_thread;
180:
181: liste_threads_surveillance = l_nouvel_objet;
182:
183: if (sem_post(&semaphore_liste_threads) != 0)
184: {
185: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
186: sigpending(&set);
187:
188: (*s_etat_processus).erreur_systeme = d_es_processus;
189: return;
190: }
191:
192: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
193: sigpending(&set);
194: return;
195: }
196:
197: void
198: retrait_thread(struct_processus *s_etat_processus)
199: {
200: sigset_t oldset;
201: sigset_t set;
202:
203: volatile struct_liste_chainee_volatile *l_element_precedent;
204: volatile struct_liste_chainee_volatile *l_element_courant;
205:
206: sigfillset(&set);
207: pthread_sigmask(SIG_BLOCK, &set, &oldset);
208:
209: while(sem_wait(&semaphore_liste_threads) == -1)
210: {
211: if (errno != EINTR)
212: {
213: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
214: sigpending(&set);
215:
216: (*s_etat_processus).erreur_systeme = d_es_processus;
217: return;
218: }
219: }
220:
221: l_element_precedent = NULL;
222: l_element_courant = liste_threads;
223:
224: while(l_element_courant != NULL)
225: {
226: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
227: == getpid()) && (pthread_equal((*((struct_thread *)
228: (*l_element_courant).donnee)).tid, pthread_self()) != 0))
229: {
230: break;
231: }
232:
233: l_element_precedent = l_element_courant;
234: l_element_courant = (*l_element_courant).suivant;
235: }
236:
237: if (l_element_courant == NULL)
238: {
239: sem_post(&semaphore_liste_threads);
240: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
241: sigpending(&set);
242:
243: (*s_etat_processus).erreur_systeme = d_es_processus;
244: return;
245: }
246:
247: if (l_element_precedent == NULL)
248: {
249: liste_threads = (*l_element_courant).suivant;
250: }
251: else
252: {
253: (*l_element_precedent).suivant = (*l_element_courant).suivant;
254: }
255:
256: free((void *) (*l_element_courant).donnee);
257: free((struct_liste_chainee_volatile *) l_element_courant);
258:
259: if (pthread_setspecific(semaphore_fork_processus_courant, NULL) != 0)
260: {
261: (*s_etat_processus).erreur_systeme = d_es_processus;
262:
263: sem_post(&semaphore_liste_threads);
264: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
265: sigpending(&set);
266: return;
267: }
268:
269: if (sem_post(&semaphore_liste_threads) != 0)
270: {
271: (*s_etat_processus).erreur_systeme = d_es_processus;
272:
273: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
274: sigpending(&set);
275: return;
276: }
277:
278: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
279: sigpending(&set);
280: return;
281: }
282:
283: void
284: retrait_thread_surveillance(struct_processus *s_etat_processus,
285: struct_descripteur_thread *s_argument_thread)
286: {
287: sigset_t set;
288: sigset_t oldset;
289:
290: volatile struct_liste_chainee_volatile *l_element_precedent;
291: volatile struct_liste_chainee_volatile *l_element_courant;
292:
293: sigfillset(&set);
294: pthread_sigmask(SIG_BLOCK, &set, &oldset);
295:
296: while(sem_wait(&semaphore_liste_threads) == -1)
297: {
298: if (errno != EINTR)
299: {
300: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
301: sigpending(&set);
302:
303: (*s_etat_processus).erreur_systeme = d_es_processus;
304: return;
305: }
306: }
307:
308: l_element_precedent = NULL;
309: l_element_courant = liste_threads_surveillance;
310:
311: while(l_element_courant != NULL)
312: {
313: if ((*l_element_courant).donnee == (void *) s_argument_thread)
314: {
315: break;
316: }
317:
318: l_element_precedent = l_element_courant;
319: l_element_courant = (*l_element_courant).suivant;
320: }
321:
322: if (l_element_courant == NULL)
323: {
324: sem_post(&semaphore_liste_threads);
325: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
326: sigpending(&set);
327:
328: (*s_etat_processus).erreur_systeme = d_es_processus;
329: return;
330: }
331:
332: if (l_element_precedent == NULL)
333: {
334: liste_threads_surveillance = (*l_element_courant).suivant;
335: }
336: else
337: {
338: (*l_element_precedent).suivant = (*l_element_courant).suivant;
339: }
340:
341: free((struct_liste_chainee_volatile *) l_element_courant);
342:
343: if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
344: {
345: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
346: sigpending(&set);
347:
348: (*s_etat_processus).erreur_systeme = d_es_processus;
349: return;
350: }
351:
352: (*s_argument_thread).nombre_references--;
353:
354: BUG((*s_argument_thread).nombre_references < 0,
355: printf("(*s_argument_thread).nombre_references = %d\n",
356: (int) (*s_argument_thread).nombre_references));
357:
358: if ((*s_argument_thread).nombre_references == 0)
359: {
360: if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
361: {
362: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
363: sigpending(&set);
364:
365: (*s_etat_processus).erreur_systeme = d_es_processus;
366: return;
367: }
368:
369: pthread_mutex_destroy(&((*s_argument_thread).mutex));
370: free(s_argument_thread);
371: }
372: else
373: {
374: if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
375: {
376: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
377: sigpending(&set);
378:
379: (*s_etat_processus).erreur_systeme = d_es_processus;
380: return;
381: }
382: }
383:
384: if (sem_post(&semaphore_liste_threads) != 0)
385: {
386: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
387: sigpending(&set);
388:
389: (*s_etat_processus).erreur_systeme = d_es_processus;
390: return;
391: }
392:
393: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
394: sigpending(&set);
395: return;
396: }
397:
398: void
399: verrouillage_threads_concurrents(struct_processus *s_etat_processus)
400: {
401: volatile struct_liste_chainee_volatile *l_element_courant;
402:
403: while(sem_wait(&semaphore_liste_threads) == -1)
404: {
405: if (errno != EINTR)
406: {
407: (*s_etat_processus).erreur_systeme = d_es_processus;
408: return;
409: }
410: }
411:
412: l_element_courant = liste_threads;
413:
414: while(l_element_courant != NULL)
415: {
416: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
417: == getpid()) && (pthread_equal((*((struct_thread *)
418: (*l_element_courant).donnee)).tid, pthread_self()) == 0))
419: {
420: while(sem_wait(&((*(*((struct_thread *) (*l_element_courant)
421: .donnee)).s_etat_processus).semaphore_fork)) == -1)
422: {
423: if (errno != EINTR)
424: {
425: (*s_etat_processus).erreur_systeme = d_es_processus;
426: return;
427: }
428: }
429: }
430:
431: l_element_courant = (*l_element_courant).suivant;
432: }
433:
434: return;
435: }
436:
437: void
438: deverrouillage_threads_concurrents(struct_processus *s_etat_processus)
439: {
440: volatile struct_liste_chainee_volatile *l_element_courant;
441:
442: l_element_courant = liste_threads;
443:
444: while(l_element_courant != NULL)
445: {
446: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
447: == getpid()) && (pthread_equal((*((struct_thread *)
448: (*l_element_courant).donnee)).tid, pthread_self()) == 0))
449: {
450: if (sem_post(&((*(*((struct_thread *)
451: (*l_element_courant).donnee)).s_etat_processus)
452: .semaphore_fork)) != 0)
453: {
454: if (sem_post(&semaphore_liste_threads) != 0)
455: {
456: (*s_etat_processus).erreur_systeme = d_es_processus;
457: return;
458: }
459:
460: (*s_etat_processus).erreur_systeme = d_es_processus;
461: return;
462: }
463: }
464:
465: l_element_courant = (*l_element_courant).suivant;
466: }
467:
468: if (sem_post(&semaphore_liste_threads) != 0)
469: {
470: (*s_etat_processus).erreur_systeme = d_es_processus;
471: return;
472: }
473:
474: return;
475: }
476:
477: void
478: liberation_threads(struct_processus *s_etat_processus)
479: {
480: logical1 suppression_variables_partagees;
481:
482: sigset_t oldset;
483: sigset_t set;
484:
485: struct_descripteur_thread *s_argument_thread;
486:
487: struct_processus *candidat;
488:
489: unsigned long i;
490:
491: void *element_candidat;
492: void *element_courant;
493: void *element_suivant;
494:
495: volatile struct_liste_chainee_volatile *l_element_courant;
496: volatile struct_liste_chainee_volatile *l_element_suivant;
497:
498: sigfillset(&set);
499: pthread_sigmask(SIG_BLOCK, &set, &oldset);
500:
501: while(sem_wait(&semaphore_liste_threads) == -1)
502: {
503: if (errno != EINTR)
504: {
505: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
506: (*s_etat_processus).erreur_systeme = d_es_processus;
507: return;
508: }
509: }
510:
511: l_element_courant = liste_threads;
512: suppression_variables_partagees = d_faux;
513:
514: while(l_element_courant != NULL)
515: {
516: if ((*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus
517: != s_etat_processus)
518: {
519: candidat = s_etat_processus;
520: s_etat_processus = (*((struct_thread *)
521: (*l_element_courant).donnee)).s_etat_processus;
522: free((*s_etat_processus).localisation);
523:
524: // (*s_etat_processus).instruction_courante peut pointer sur
525: // n'importe quoi (une instruction courante ou un champ d'une
526: // structure objet). On ne le libère pas quitte à avoir une
527: // petite fuite mémoire dans le processus fils.
528:
529: if ((*s_etat_processus).instruction_courante != NULL)
530: {
531: //free((*s_etat_processus).instruction_courante);
532: }
533:
534: close((*s_etat_processus).pipe_acquittement);
535: close((*s_etat_processus).pipe_donnees);
536: close((*s_etat_processus).pipe_injections);
537: close((*s_etat_processus).pipe_nombre_injections);
538: close((*s_etat_processus).pipe_interruptions);
539: close((*s_etat_processus).pipe_nombre_objets_attente);
540: close((*s_etat_processus).pipe_nombre_interruptions_attente);
541:
542: if ((*s_etat_processus).nom_fichier_impression != NULL)
543: {
544: free((*s_etat_processus).nom_fichier_impression);
545: }
546:
547: while((*s_etat_processus).fichiers_graphiques != NULL)
548: {
549: free((*(*s_etat_processus).fichiers_graphiques).nom);
550:
551: if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL)
552: {
553: free((*(*s_etat_processus).fichiers_graphiques).legende);
554: }
555:
556: element_courant = (*s_etat_processus).fichiers_graphiques;
557: (*s_etat_processus).fichiers_graphiques =
558: (*(*s_etat_processus).fichiers_graphiques).suivant;
559:
560: free(element_courant);
561: }
562:
563: if ((*s_etat_processus).entree_standard != NULL)
564: {
565: pclose((*s_etat_processus).entree_standard);
566: }
567:
568: if ((*s_etat_processus).generateur_aleatoire != NULL)
569: {
570: liberation_generateur_aleatoire(s_etat_processus);
571: }
572:
573: if ((*s_etat_processus).instruction_derniere_erreur != NULL)
574: {
575: free((*s_etat_processus).instruction_derniere_erreur);
576: (*s_etat_processus).instruction_derniere_erreur = NULL;
577: }
578:
579: element_courant = (void *) (*s_etat_processus)
580: .l_base_pile_processus;
581: while(element_courant != NULL)
582: {
583: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
584: element_courant)).donnee).mutex));
585: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
586: element_courant)).donnee).mutex));
587: liberation(s_etat_processus,
588: (*((struct_liste_chainee *) element_courant)).donnee);
589: element_suivant = (*((struct_liste_chainee *) element_courant))
590: .suivant;
591: free((struct_liste_chainee *) element_courant);
592: element_courant = element_suivant;
593: }
594:
595: pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));
596: pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));
597: liberation(s_etat_processus, (*s_etat_processus).indep);
598:
599: pthread_mutex_trylock(&((*(*s_etat_processus).depend).mutex));
600: pthread_mutex_unlock(&((*(*s_etat_processus).depend).mutex));
601: liberation(s_etat_processus, (*s_etat_processus).depend);
602:
603: free((*s_etat_processus).label_x);
604: free((*s_etat_processus).label_y);
605: free((*s_etat_processus).label_z);
606: free((*s_etat_processus).titre);
607: free((*s_etat_processus).legende);
608:
609: pthread_mutex_trylock(&((*(*s_etat_processus)
610: .parametres_courbes_de_niveau).mutex));
611: pthread_mutex_unlock(&((*(*s_etat_processus)
612: .parametres_courbes_de_niveau).mutex));
613: liberation(s_etat_processus, (*s_etat_processus)
614: .parametres_courbes_de_niveau);
615:
616: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
617: {
618: if ((*s_etat_processus).corps_interruptions[i] != NULL)
619: {
620: pthread_mutex_trylock(&((*(*s_etat_processus)
621: .corps_interruptions[i]).mutex));
622: pthread_mutex_unlock(&((*(*s_etat_processus)
623: .corps_interruptions[i]).mutex));
624:
625: liberation(s_etat_processus,
626: (*s_etat_processus).corps_interruptions[i]);
627: }
628:
629: element_courant = (*s_etat_processus)
630: .pile_origine_interruptions[i];
631:
632: while(element_courant != NULL)
633: {
634: element_suivant = (*((struct_liste_chainee *)
635: element_courant)).suivant;
636:
637: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
638: element_courant)).donnee).mutex));
639: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
640: element_courant)).donnee).mutex));
641:
642: liberation(s_etat_processus,
643: (*((struct_liste_chainee *) element_courant))
644: .donnee);
645: free(element_courant);
646:
647: element_courant = element_suivant;
648: }
649: }
650:
651: for(i = 0; i < (*s_etat_processus).nombre_variables; i++)
652: {
653: pthread_mutex_trylock(&((*(*s_etat_processus)
654: .s_liste_variables[i].objet).mutex));
655: pthread_mutex_unlock(&((*(*s_etat_processus)
656: .s_liste_variables[i].objet).mutex));
657:
658: // Les variables de niveau 0 sont des définitions qui
659: // ne sont pas copiées entre threads.
660: if ((*s_etat_processus).s_liste_variables[i].niveau > 0)
661: {
662: liberation(s_etat_processus,
663: (*s_etat_processus).s_liste_variables[i].objet);
664: }
665:
666: free((*s_etat_processus).s_liste_variables[i].nom);
667: }
668:
669: free((*s_etat_processus).s_liste_variables);
670:
671: for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
672: {
673: pthread_mutex_trylock(&((*(*s_etat_processus)
674: .s_liste_variables_statiques[i].objet).mutex));
675: pthread_mutex_unlock(&((*(*s_etat_processus)
676: .s_liste_variables_statiques[i].objet).mutex));
677:
678: liberation(s_etat_processus, (*s_etat_processus)
679: .s_liste_variables_statiques[i].objet);
680: free((*s_etat_processus).s_liste_variables_statiques[i].nom);
681: }
682:
683: free((*s_etat_processus).s_liste_variables_statiques);
684:
685: // Ne peut être effacé qu'une seule fois
686: if (suppression_variables_partagees == d_faux)
687: {
688: suppression_variables_partagees = d_vrai;
689:
690: for(i = 0; i < (*(*s_etat_processus)
691: .s_liste_variables_partagees).nombre_variables; i++)
692: {
693: pthread_mutex_trylock(&((*(*(*s_etat_processus)
694: .s_liste_variables_partagees).table[i].objet)
695: .mutex));
696: pthread_mutex_unlock(&((*(*(*s_etat_processus)
697: .s_liste_variables_partagees).table[i].objet)
698: .mutex));
699:
700: liberation(s_etat_processus, (*(*s_etat_processus)
701: .s_liste_variables_partagees).table[i].objet);
702: free((*(*s_etat_processus).s_liste_variables_partagees)
703: .table[i].nom);
704: }
705:
706: if ((*(*s_etat_processus).s_liste_variables_partagees).table
707: != NULL)
708: {
709: free((struct_variable_partagee *) (*(*s_etat_processus)
710: .s_liste_variables_partagees).table);
711: }
712:
713: pthread_mutex_trylock(&((*(*s_etat_processus)
714: .s_liste_variables_partagees).mutex));
715: pthread_mutex_unlock(&((*(*s_etat_processus)
716: .s_liste_variables_partagees).mutex));
717: }
718:
719: element_courant = (*s_etat_processus).l_base_pile;
720: while(element_courant != NULL)
721: {
722: element_suivant = (*((struct_liste_chainee *)
723: element_courant)).suivant;
724:
725: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
726: element_courant)).donnee).mutex));
727: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
728: element_courant)).donnee).mutex));
729:
730: liberation(s_etat_processus,
731: (*((struct_liste_chainee *)
732: element_courant)).donnee);
733: free((struct_liste_chainee *) element_courant);
734:
735: element_courant = element_suivant;
736: }
737:
738: element_courant = (*s_etat_processus).l_base_pile_contextes;
739: while(element_courant != NULL)
740: {
741: element_suivant = (*((struct_liste_chainee *)
742: element_courant)).suivant;
743:
744: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
745: element_courant)).donnee).mutex));
746: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
747: element_courant)).donnee).mutex));
748: liberation(s_etat_processus, (*((struct_liste_chainee *)
749: element_courant)).donnee);
750: free((struct_liste_chainee *) element_courant);
751:
752: element_courant = element_suivant;
753: }
754:
755: element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
756: while(element_courant != NULL)
757: {
758: element_suivant = (*((struct_liste_chainee *)
759: element_courant)).suivant;
760:
761: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
762: element_courant)).donnee).mutex));
763: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
764: element_courant)).donnee).mutex));
765: liberation(s_etat_processus,
766: (*((struct_liste_chainee *)
767: element_courant)).donnee);
768: free((struct_liste_chainee *) element_courant);
769:
770: element_courant = element_suivant;
771: }
772:
773: for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
774: i++)
775: {
776: free((*s_etat_processus).s_instructions_externes[i].nom);
777: free((*s_etat_processus).s_instructions_externes[i]
778: .nom_bibliotheque);
779: }
780:
781: if ((*s_etat_processus).nombre_instructions_externes != 0)
782: {
783: free((*s_etat_processus).s_instructions_externes);
784: }
785:
786: element_courant = (*s_etat_processus).s_bibliotheques;
787: while(element_courant != NULL)
788: {
789: element_suivant = (*((struct_liste_chainee *)
790: element_courant)).suivant;
791:
792: element_candidat = (*candidat).s_bibliotheques;
793: while(element_candidat != NULL)
794: {
795: if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
796: element_courant)).donnee))
797: .descripteur == (*((struct_bibliotheque *)
798: (*((struct_liste_chainee *) element_candidat))
799: .donnee)).descripteur) &&
800: ((*((struct_bibliotheque *)
801: (*((struct_liste_chainee *) element_courant))
802: .donnee)).pid == (*((struct_bibliotheque *)
803: (*((struct_liste_chainee *) element_candidat))
804: .donnee)).pid) && (pthread_equal(
805: (*((struct_bibliotheque *)
806: (*((struct_liste_chainee *) element_courant))
807: .donnee)).tid, (*((struct_bibliotheque *)
808: (*((struct_liste_chainee *) element_candidat))
809: .donnee)).tid) != 0))
810: {
811: break;
812: }
813:
814: element_candidat = (*((struct_liste_chainee *)
815: element_candidat)).suivant;
816: }
817:
818: if (element_candidat == NULL)
819: {
820: dlclose((*((struct_bibliotheque *)
821: (*((struct_liste_chainee *) element_courant))
822: .donnee)).descripteur);
823: }
824:
825: free((*((struct_bibliotheque *)
826: (*((struct_liste_chainee *)
827: element_courant)).donnee)).nom);
828: free((*((struct_liste_chainee *) element_courant)).donnee);
829: free(element_courant);
830:
831: element_courant = element_suivant;
832: }
833:
834: element_courant = (*s_etat_processus).l_base_pile_last;
835: while(element_courant != NULL)
836: {
837: element_suivant = (*((struct_liste_chainee *)
838: element_courant)).suivant;
839:
840: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
841: element_courant)).donnee).mutex));
842: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
843: element_courant)).donnee).mutex));
844: liberation(s_etat_processus,
845: (*((struct_liste_chainee *) element_courant)).donnee);
846: free(element_courant);
847:
848: element_courant = element_suivant;
849: }
850:
851: element_courant = (*s_etat_processus).l_base_pile_systeme;
852: while(element_courant != NULL)
853: {
854: element_suivant = (*((struct_liste_pile_systeme *)
855: element_courant)).suivant;
856:
857: if ((*((struct_liste_pile_systeme *)
858: element_courant)).indice_boucle != NULL)
859: {
860: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
861: element_courant)).indice_boucle).mutex));
862: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
863: element_courant)).indice_boucle).mutex));
864: }
865:
866: liberation(s_etat_processus,
867: (*((struct_liste_pile_systeme *)
868: element_courant)).indice_boucle);
869:
870: if ((*((struct_liste_pile_systeme *)
871: element_courant)).limite_indice_boucle != NULL)
872: {
873: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
874: element_courant)).limite_indice_boucle).mutex));
875: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
876: element_courant)).limite_indice_boucle).mutex));
877: }
878:
879: liberation(s_etat_processus,
880: (*((struct_liste_pile_systeme *)
881: element_courant)).limite_indice_boucle);
882:
883: if ((*((struct_liste_pile_systeme *)
884: element_courant)).objet_de_test != NULL)
885: {
886: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
887: element_courant)).objet_de_test).mutex));
888: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
889: element_courant)).objet_de_test).mutex));
890: }
891:
892: liberation(s_etat_processus,
893: (*((struct_liste_pile_systeme *)
894: element_courant)).objet_de_test);
895:
896: if ((*((struct_liste_pile_systeme *)
897: element_courant)).nom_variable != NULL)
898: {
899: free((*((struct_liste_pile_systeme *)
900: element_courant)).nom_variable);
901: }
902:
903: free(element_courant);
904:
905: element_courant = element_suivant;
906: }
907:
908: element_courant = (*s_etat_processus).s_fichiers;
909: while(element_courant != NULL)
910: {
911: element_suivant = (*((struct_liste_chainee *)
912: element_courant)).suivant;
913:
914: element_candidat = (*candidat).s_fichiers;
915: while(element_candidat != NULL)
916: {
917: if (((*((struct_descripteur_fichier *)
918: (*((struct_liste_chainee *) element_courant))
919: .donnee)).pid ==
920: (*((struct_descripteur_fichier *)
921: (*((struct_liste_chainee *) element_candidat))
922: .donnee)).pid) && (pthread_equal(
923: (*((struct_descripteur_fichier *)
924: (*((struct_liste_chainee *) element_courant))
925: .donnee)).tid, (*((struct_descripteur_fichier *)
926: (*((struct_liste_chainee *) element_candidat))
927: .donnee)).tid) != 0))
928: {
1.5 bertrand 929: if ((*((struct_descripteur_fichier *)
930: (*((struct_liste_chainee *) element_courant))
931: .donnee)).type ==
932: (*((struct_descripteur_fichier *)
933: (*((struct_liste_chainee *) element_candidat))
934: .donnee)).type)
935: {
936: if ((*((struct_descripteur_fichier *)
937: (*((struct_liste_chainee *)
938: element_candidat)).donnee)).type == 'C')
939: {
940: if ((*((struct_descripteur_fichier *)
941: (*((struct_liste_chainee *)
942: element_courant)).donnee))
943: .descripteur_c ==
944: (*((struct_descripteur_fichier *)
945: (*((struct_liste_chainee *)
946: element_candidat)).donnee))
947: .descripteur_c)
948: {
949: break;
950: }
951: }
952: else
953: {
954: if (((*((struct_descripteur_fichier *)
955: (*((struct_liste_chainee *)
956: element_courant)).donnee))
957: .descripteur_sqlite ==
958: (*((struct_descripteur_fichier *)
959: (*((struct_liste_chainee *)
960: element_candidat)).donnee))
961: .descripteur_sqlite) &&
962: ((*((struct_descripteur_fichier *)
963: (*((struct_liste_chainee *)
964: element_courant)).donnee))
965: .descripteur_c ==
966: (*((struct_descripteur_fichier *)
967: (*((struct_liste_chainee *)
968: element_candidat)).donnee))
969: .descripteur_c))
970: {
971: break;
972: }
973: }
974: }
1.1 bertrand 975: }
976:
977: element_candidat = (*((struct_liste_chainee *)
978: element_candidat)).suivant;
979: }
980:
981: if (element_candidat == NULL)
982: {
983: fclose((*((struct_descripteur_fichier *)
984: (*((struct_liste_chainee *) element_courant))
1.5 bertrand 985: .donnee)).descripteur_c);
986:
987: if ((*((struct_descripteur_fichier *)
988: (*((struct_liste_chainee *) element_courant))
989: .donnee)).type != 'C')
990: {
991: sqlite3_close((*((struct_descripteur_fichier *)
992: (*((struct_liste_chainee *) element_courant))
993: .donnee)).descripteur_sqlite);
994: }
1.1 bertrand 995: }
996:
997: free((*((struct_descripteur_fichier *)
998: (*((struct_liste_chainee *)
999: element_courant)).donnee)).nom);
1000: free((struct_descripteur_fichier *)
1001: (*((struct_liste_chainee *)
1002: element_courant)).donnee);
1003: free(element_courant);
1004:
1005: element_courant = element_suivant;
1006: }
1007:
1008: element_courant = (*s_etat_processus).s_sockets;
1009: while(element_courant != NULL)
1010: {
1011: element_suivant = (*((struct_liste_chainee *)
1012: element_courant)).suivant;
1013:
1014: element_candidat = (*candidat).s_sockets;
1015: while(element_candidat != NULL)
1016: {
1017: if (((*((struct_socket *)
1018: (*((struct_liste_chainee *) element_courant))
1019: .donnee)).socket == (*((struct_socket *)
1020: (*((struct_liste_chainee *) element_candidat))
1021: .donnee)).socket) &&
1022: ((*((struct_socket *)
1023: (*((struct_liste_chainee *) element_courant))
1024: .donnee)).pid == (*((struct_socket *)
1025: (*((struct_liste_chainee *) element_candidat))
1026: .donnee)).pid) && (pthread_equal(
1027: (*((struct_socket *)
1028: (*((struct_liste_chainee *) element_courant))
1029: .donnee)).tid, (*((struct_socket *)
1030: (*((struct_liste_chainee *) element_candidat))
1031: .donnee)).tid) != 0))
1032: {
1033: break;
1034: }
1035:
1036: element_candidat = (*((struct_liste_chainee *)
1037: element_candidat)).suivant;
1038: }
1039:
1040: if (element_candidat == NULL)
1041: {
1042: if ((*((struct_socket *) (*((struct_liste_chainee *)
1043: element_courant)).donnee)).socket_connectee
1044: == d_vrai)
1045: {
1046: shutdown((*((struct_socket *)
1047: (*((struct_liste_chainee *) element_courant))
1048: .donnee)).socket, SHUT_RDWR);
1049: }
1050:
1051: close((*((struct_socket *)
1052: (*((struct_liste_chainee *) element_courant))
1053: .donnee)).socket);
1054: }
1055:
1056: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1057: element_courant)).donnee).mutex));
1058: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1059: element_courant)).donnee).mutex));
1060:
1061: liberation(s_etat_processus,
1062: (*((struct_liste_chainee *)
1063: element_courant)).donnee);
1064: free(element_courant);
1065:
1066: element_courant = element_suivant;
1067: }
1068:
1069: element_courant = (*s_etat_processus).s_connecteurs_sql;
1070: while(element_courant != NULL)
1071: {
1072: element_suivant = (*((struct_liste_chainee *)
1073: element_courant)).suivant;
1074:
1075: element_candidat = (*candidat).s_connecteurs_sql;
1076: while(element_candidat != NULL)
1077: {
1078: if (((
1079: #ifdef MYSQL_SUPPORT
1080: ((*((struct_connecteur_sql *)
1081: (*((struct_liste_chainee *) element_courant))
1082: .donnee)).descripteur.mysql ==
1083: (*((struct_connecteur_sql *)
1084: (*((struct_liste_chainee *) element_candidat))
1085: .donnee)).descripteur.mysql)
1086: &&
1087: (strcmp((*((struct_connecteur_sql *)
1088: (*((struct_liste_chainee *) element_courant))
1089: .donnee)).type, "MYSQL") == 0)
1090: &&
1091: (strcmp((*((struct_connecteur_sql *)
1092: (*((struct_liste_chainee *) element_candidat))
1093: .donnee)).type, "MYSQL") == 0)
1094: #else
1095: 0
1096: #endif
1097: ) || (
1098: #ifdef POSTGRESQL_SUPPORT
1099: ((*((struct_connecteur_sql *)
1100: (*((struct_liste_chainee *) element_courant))
1101: .donnee)).descripteur.postgresql ==
1102: (*((struct_connecteur_sql *)
1103: (*((struct_liste_chainee *) element_candidat))
1104: .donnee)).descripteur.postgresql)
1105: &&
1106: (strcmp((*((struct_connecteur_sql *)
1107: (*((struct_liste_chainee *) element_courant))
1108: .donnee)).type, "POSTGRESQL") == 0)
1109: &&
1110: (strcmp((*((struct_connecteur_sql *)
1111: (*((struct_liste_chainee *) element_candidat))
1112: .donnee)).type, "POSTGRESQL") == 0)
1113: #else
1114: 0
1115: #endif
1116: )) &&
1117: ((*((struct_connecteur_sql *)
1118: (*((struct_liste_chainee *) element_courant))
1119: .donnee)).pid == (*((struct_connecteur_sql *)
1120: (*((struct_liste_chainee *) element_candidat))
1121: .donnee)).pid) && (pthread_equal(
1122: (*((struct_connecteur_sql *)
1123: (*((struct_liste_chainee *) element_courant))
1124: .donnee)).tid, (*((struct_connecteur_sql *)
1125: (*((struct_liste_chainee *) element_candidat))
1126: .donnee)).tid) != 0))
1127: {
1128: break;
1129: }
1130:
1131: element_candidat = (*((struct_liste_chainee *)
1132: element_candidat)).suivant;
1133: }
1134:
1135: if (element_candidat == NULL)
1136: {
1137: sqlclose((*((struct_liste_chainee *) element_courant))
1138: .donnee);
1139: }
1140:
1141: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1142: element_courant)).donnee).mutex));
1143: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1144: element_courant)).donnee).mutex));
1145:
1146: liberation(s_etat_processus, (*((struct_liste_chainee *)
1147: element_courant)).donnee);
1148: free(element_courant);
1149:
1150: element_courant = element_suivant;
1151: }
1152:
1153: element_courant = (*s_etat_processus).s_marques;
1154: while(element_courant != NULL)
1155: {
1156: free((*((struct_marque *) element_courant)).label);
1157: free((*((struct_marque *) element_courant)).position);
1158: element_suivant = (*((struct_marque *) element_courant))
1159: .suivant;
1160: free(element_courant);
1161: element_courant = element_suivant;
1162: }
1163:
1164: liberation_allocateur(s_etat_processus);
1165:
1166: sem_post(&((*s_etat_processus).semaphore_fork));
1167: sem_destroy(&((*s_etat_processus).semaphore_fork));
1168:
1169: free(s_etat_processus);
1170:
1171: s_etat_processus = candidat;
1172: }
1173:
1174: l_element_suivant = (*l_element_courant).suivant;
1175:
1176: free((struct_thread *) (*l_element_courant).donnee);
1177: free((struct_liste_chainee *) l_element_courant);
1178:
1179: l_element_courant = l_element_suivant;
1180: }
1181:
1182: liste_threads = NULL;
1183:
1184: l_element_courant = liste_threads_surveillance;
1185:
1186: while(l_element_courant != NULL)
1187: {
1188: s_argument_thread = (struct_descripteur_thread *)
1189: (*l_element_courant).donnee;
1190:
1191: close((*s_argument_thread).pipe_objets[0]);
1192: close((*s_argument_thread).pipe_acquittement[1]);
1193: close((*s_argument_thread).pipe_injections[1]);
1194: close((*s_argument_thread).pipe_nombre_injections[1]);
1195: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
1196: close((*s_argument_thread).pipe_interruptions[0]);
1197: close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
1198:
1199: if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
1200: {
1201: (*s_etat_processus).erreur_systeme = d_es_processus;
1202: return;
1203: }
1204:
1205: (*s_argument_thread).nombre_references--;
1206:
1207: BUG((*s_argument_thread).nombre_references < 0,
1208: printf("(*s_argument_thread).nombre_references = %d\n",
1209: (int) (*s_argument_thread).nombre_references));
1210:
1211: if ((*s_argument_thread).nombre_references == 0)
1212: {
1213: if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
1214: {
1215: (*s_etat_processus).erreur_systeme = d_es_processus;
1216: return;
1217: }
1218:
1219: pthread_mutex_destroy(&((*s_argument_thread).mutex));
1220: free(s_argument_thread);
1221: }
1222: else
1223: {
1224: if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
1225: {
1226: (*s_etat_processus).erreur_systeme = d_es_processus;
1227: return;
1228: }
1229: }
1230:
1231: l_element_suivant = (*l_element_courant).suivant;
1232: free((struct_liste_chainee *) l_element_courant);
1233: l_element_courant = l_element_suivant;
1234: }
1235:
1236: liste_threads_surveillance = NULL;
1237:
1238: if (sem_post(&semaphore_liste_threads) != 0)
1239: {
1240: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1241: (*s_etat_processus).erreur_systeme = d_es_processus;
1242: return;
1243: }
1244:
1245: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1246: sigpending(&set);
1247: return;
1248: }
1249:
1250: static struct_processus *
1251: recherche_thread(pid_t pid, pthread_t tid)
1252: {
1253: volatile struct_liste_chainee_volatile *l_element_courant;
1254:
1255: struct_processus *s_etat_processus;
1256:
1257: l_element_courant = liste_threads;
1258:
1259: while(l_element_courant != NULL)
1260: {
1261: if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
1262: .tid, tid) != 0) && ((*((struct_thread *)
1263: (*l_element_courant).donnee)).pid == pid))
1264: {
1265: break;
1266: }
1267:
1268: l_element_courant = (*l_element_courant).suivant;
1269: }
1270:
1271: if (l_element_courant == NULL)
1272: {
1273: /*
1274: * Le processus n'existe plus. On ne distribue aucun signal.
1275: */
1276:
1277: return(NULL);
1278: }
1279:
1280: s_etat_processus = (*((struct_thread *)
1281: (*l_element_courant).donnee)).s_etat_processus;
1282:
1283: return(s_etat_processus);
1284: }
1285:
1286: static logical1
1287: recherche_thread_principal(pid_t pid, pthread_t *thread)
1288: {
1289: volatile struct_liste_chainee_volatile *l_element_courant;
1290:
1291: l_element_courant = liste_threads;
1292:
1293: while(l_element_courant != NULL)
1294: {
1295: if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
1296: == d_vrai) && ((*((struct_thread *)
1297: (*l_element_courant).donnee)).pid == pid))
1298: {
1299: break;
1300: }
1301:
1302: l_element_courant = (*l_element_courant).suivant;
1303: }
1304:
1305: if (l_element_courant == NULL)
1306: {
1307: /*
1308: * Le processus n'existe plus. On ne distribue aucun signal.
1309: */
1310:
1311: return(d_faux);
1312: }
1313:
1314: (*thread) = (*((struct_thread *) (*l_element_courant).donnee)).tid;
1315:
1316: return(d_vrai);
1317: }
1318:
1319:
1320: /*
1321: ================================================================================
1322: Procédures de gestion des signaux d'interruption
1323: ================================================================================
1324: Entrée : variable globale
1325: --------------------------------------------------------------------------------
1326: Sortie : variable globale modifiée
1327: --------------------------------------------------------------------------------
1328: Effets de bord : néant
1329: ================================================================================
1330: */
1331:
1332: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
1333: // des signaux asynchrones. Elles de doivent pas bloquer dans le cas où
1334: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
1335:
1336: static inline void
1337: verrouillage_gestionnaire_signaux()
1338: {
1339: int semaphore;
1340:
1341: sigset_t oldset;
1342: sigset_t set;
1343:
1344: sem_t *sem;
1345:
1346: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1347: != NULL)
1348: {
1349: if (sem_post(sem) != 0)
1350: {
1351: BUG(1, uprintf("Lock error !\n"));
1352: return;
1353: }
1354: }
1355:
1356: // Il faut respecteur l'atomicité des deux opérations suivantes !
1357:
1358: sigfillset(&set);
1359: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1360:
1361: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1362: {
1363: if (errno != EINTR)
1364: {
1365: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1366: BUG(1, uprintf("Unlock error !\n"));
1367: return;
1368: }
1369: }
1370:
1371: if (sem_post(&semaphore_gestionnaires_signaux) == -1)
1372: {
1373: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1374: BUG(1, uprintf("Lock error !\n"));
1375: return;
1376: }
1377:
1378: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1379: {
1380: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1381: BUG(1, uprintf("Lock error !\n"));
1382: return;
1383: }
1384:
1385: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1386: {
1387: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1388: BUG(1, uprintf("Unlock error !\n"));
1389: return;
1390: }
1391:
1392: if (semaphore == 1)
1393: {
1394: // Le semaphore ne peut être pris par le thread qui a appelé
1395: // le gestionnaire de signal car le signal est bloqué par ce thread
1396: // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
1397: // par un thread concurrent. On essaye donc de le bloquer jusqu'à
1398: // ce que ce soit possible.
1399:
1400: while(sem_trywait(&semaphore_liste_threads) == -1)
1401: {
1402: if ((errno != EINTR) && (errno != EAGAIN))
1403: {
1404: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1405:
1406: while(sem_wait(sem) == -1)
1407: {
1408: if (errno != EINTR)
1409: {
1410: BUG(1, uprintf("Lock error !\n"));
1411: return;
1412: }
1413: }
1414:
1415: BUG(1, uprintf("Lock error !\n"));
1416: return;
1417: }
1418:
1419: sched_yield();
1420: }
1421: }
1422:
1423: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1424: sigpending(&set);
1425:
1426: return;
1427: }
1428:
1429: static inline void
1430: deverrouillage_gestionnaire_signaux()
1431: {
1432: int semaphore;
1433:
1434: sem_t *sem;
1435:
1436: sigset_t oldset;
1437: sigset_t set;
1438:
1439: // Il faut respecteur l'atomicité des deux opérations suivantes !
1440:
1441: sigfillset(&set);
1442: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1443:
1444: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1445: {
1446: if (errno != EINTR)
1447: {
1448: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1449: BUG(1, uprintf("Unlock error !\n"));
1450: return;
1451: }
1452: }
1453:
1454: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1455: {
1456: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1457: BUG(1, uprintf("Unlock error !\n"));
1458: return;
1459: }
1460:
1461: while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1462: {
1463: if (errno != EINTR)
1464: {
1465: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1466: BUG(1, uprintf("Unlock error !\n"));
1467: return;
1468: }
1469: }
1470:
1471: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1472: {
1473: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1474: BUG(1, uprintf("Unlock error !\n"));
1475: return;
1476: }
1477:
1478: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1479: != NULL)
1480: {
1481: while(sem_wait(sem) == -1)
1482: {
1483: if (errno != EINTR)
1484: {
1485: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1486: BUG(1, uprintf("Unlock error !\n"));
1487: return;
1488: }
1489: }
1490: }
1491:
1492: if (semaphore == 1)
1493: {
1494: if (sem_post(&semaphore_liste_threads) != 0)
1495: {
1496: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1497:
1498: BUG(1, uprintf("Unlock error !\n"));
1499: return;
1500: }
1501: }
1502:
1503: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1504: sigpending(&set);
1505:
1506: return;
1507: }
1508:
1509: void
1510: interruption1(int signal, siginfo_t *siginfo, void *context)
1511: {
1512: pthread_t thread;
1513:
1514: struct_processus *s_etat_processus;
1515:
1516: volatile sig_atomic_t exclusion = 0;
1517:
1518: verrouillage_gestionnaire_signaux();
1519:
1520: switch(signal)
1521: {
1522: case SIGALRM :
1523: {
1524: if ((*siginfo).si_pid == getpid())
1525: {
1526: if ((s_etat_processus = recherche_thread(getpid(),
1527: pthread_self())) == NULL)
1528: {
1529: deverrouillage_gestionnaire_signaux();
1530: return;
1531: }
1532:
1533: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1534: {
1535: printf("[%d] SIGALRM (thread %llu)\n", (int) getpid(),
1536: (unsigned long long) pthread_self());
1537: fflush(stdout);
1538: }
1539:
1540: if ((*s_etat_processus).pid_processus_pere != getpid())
1541: {
1542: kill((*s_etat_processus).pid_processus_pere, signal);
1543: }
1544: else
1545: {
1546: (*s_etat_processus).var_volatile_alarme = -1;
1547: (*s_etat_processus).var_volatile_requete_arret = -1;
1548: }
1549: }
1550: else
1551: {
1552: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1553: {
1554: pthread_kill(thread, signal);
1555: }
1556: }
1557:
1558: break;
1559: }
1560:
1561: case SIGINT :
1562: {
1563: /*
1564: * Une vieille spécification POSIX permet au pointeur siginfo
1565: * d'être nul dans le cas d'un ^C envoyé depuis le clavier.
1566: * Solaris suit en particulier cette spécification.
1567: */
1568:
1569: if (siginfo == NULL)
1570: {
1571: kill(getpid(), signal);
1572: }
1573: else if ((*siginfo).si_pid == getpid())
1574: {
1575: if ((s_etat_processus = recherche_thread(getpid(),
1576: pthread_self())) == NULL)
1577: {
1578: deverrouillage_gestionnaire_signaux();
1579: return;
1580: }
1581:
1582: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1583: {
1584: printf("[%d] SIGINT (thread %llu)\n", (int) getpid(),
1585: (unsigned long long) pthread_self());
1586: fflush(stdout);
1587: }
1588:
1589: if ((*s_etat_processus).pid_processus_pere != getpid())
1590: {
1591: kill((*s_etat_processus).pid_processus_pere, signal);
1592: }
1593: else
1594: {
1595: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1596:
1597: while(exclusion == 1);
1598: exclusion = 1;
1599:
1600: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1601: {
1602: deverrouillage_gestionnaire_signaux();
1603: exclusion = 0;
1604: return;
1605: }
1606:
1607: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1608: {
1609: printf("+++Interruption\n");
1610: }
1611: else
1612: {
1613: printf("+++Interrupt\n");
1614: }
1615:
1616: fflush(stdout);
1617:
1618: (*s_etat_processus).var_volatile_requete_arret = -1;
1619: (*s_etat_processus).var_volatile_alarme = -1;
1620:
1621: exclusion = 0;
1622: }
1623: }
1624: else
1625: {
1626: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1627: {
1628: pthread_kill(thread, signal);
1629: }
1630: }
1631:
1632: break;
1633: }
1634:
1635: default :
1636: {
1637: BUG(1, uprintf("[%d] Unknown signal %d in this context\n",
1638: (int) getpid(), signal));
1639: break;
1640: }
1641: }
1642:
1643: deverrouillage_gestionnaire_signaux();
1644: return;
1645: }
1646:
1647: void
1648: interruption2(int signal, siginfo_t *siginfo, void *context)
1649: {
1650: pthread_t thread;
1651: struct_processus *s_etat_processus;
1652:
1653: verrouillage_gestionnaire_signaux();
1654:
1655: if (siginfo == NULL)
1656: {
1657: /*
1658: * Le signal SIGFSTP provient de la mort du processus de contrôle.
1659: * Sous certains systèmes (Linux...), la mort du terminal de contrôle
1660: * se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
1661: * (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
1662: * non initialisée (pointeur NULL) issue de TERMIO.
1663: */
1664:
1665: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1666: {
1667: pthread_kill(thread, SIGHUP);
1668: deverrouillage_gestionnaire_signaux();
1669: return;
1670: }
1671: }
1672: else if ((*siginfo).si_pid == getpid())
1673: {
1674: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1675: == NULL)
1676: {
1677: deverrouillage_gestionnaire_signaux();
1678: return;
1679: }
1680:
1681: /*
1682: * 0 => fonctionnement normal
1683: * -1 => requête
1684: * 1 => requête acceptée en attente de traitement
1685: */
1686:
1687: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1688: {
1689: printf("[%d] SIGTSTP (thread %llu)\n", (int) getpid(),
1690: (unsigned long long) pthread_self());
1691: fflush(stdout);
1692: }
1693:
1694: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1695: {
1696: kill((*s_etat_processus).pid_processus_pere, signal);
1697: }
1698: else
1699: {
1700: (*s_etat_processus).var_volatile_requete_arret2 = -1;
1701: }
1702: }
1703: else
1704: {
1705: // Envoi d'un signal au thread maître du groupe.
1706:
1707: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1708: {
1709: pthread_kill(thread, SIGTSTP);
1710: deverrouillage_gestionnaire_signaux();
1711: return;
1712: }
1713: }
1714:
1715: deverrouillage_gestionnaire_signaux();
1716: return;
1717: }
1718:
1719: void
1720: interruption3(int signal, siginfo_t *siginfo, void *context)
1721: {
1722: struct_processus *s_etat_processus;
1723:
1724: static int compteur = 0;
1725:
1726: verrouillage_gestionnaire_signaux();
1727:
1728: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1729: {
1730: deverrouillage_gestionnaire_signaux();
1731: return;
1732: }
1733:
1734: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1735: {
1736: printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
1737: (unsigned long long) pthread_self());
1738: fflush(stdout);
1739: }
1740:
1741: if ((*s_etat_processus).var_volatile_recursivite == -1)
1742: {
1743: // Segfault dans un appel de fonction récursive
1744: deverrouillage_gestionnaire_signaux();
1745: longjmp(contexte, -1);
1746: }
1747: else
1748: {
1749: // Segfault dans une routine interne
1750: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1751: {
1752: printf("+++Système : Violation d'accès (dépassement de pile)\n");
1753: }
1754: else
1755: {
1756: printf("+++System : Access violation (stack overflow)\n");
1757: }
1758:
1759: fflush(stdout);
1760:
1761: compteur++;
1762:
1763: if (compteur > 1)
1764: {
1765: deverrouillage_gestionnaire_signaux();
1766: exit(EXIT_FAILURE);
1767: }
1768: else
1769: {
1770: deverrouillage_gestionnaire_signaux();
1771: longjmp(contexte_initial, -1);
1772: }
1773: }
1774:
1775: deverrouillage_gestionnaire_signaux();
1776: return;
1777: }
1778:
1779: void
1780: interruption4(int signal, siginfo_t *siginfo, void *context)
1781: {
1782: struct_processus *s_etat_processus;
1783:
1784: verrouillage_gestionnaire_signaux();
1785:
1786: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1787: {
1788: deverrouillage_gestionnaire_signaux();
1789: return;
1790: }
1791:
1792: /*
1793: * Démarrage d'un processus fils ou gestion de SIGCONT (SUSPEND)
1794: */
1795:
1796: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1797: {
1798: printf("[%d] SIGSTART/SIGCONT (thread %llu)\n", (int) getpid(),
1799: (unsigned long long) pthread_self());
1800: fflush(stdout);
1801: }
1802:
1803: deverrouillage_gestionnaire_signaux();
1804: return;
1805: }
1806:
1807: void
1808: interruption5(int signal, siginfo_t *siginfo, void *context)
1809: {
1810: pthread_t thread;
1811: struct_processus *s_etat_processus;
1812:
1813: verrouillage_gestionnaire_signaux();
1814:
1815: if ((*siginfo).si_pid == getpid())
1816: {
1817: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1818: == NULL)
1819: {
1820: deverrouillage_gestionnaire_signaux();
1821: return;
1822: }
1823:
1824: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1825: {
1826: printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(),
1827: (unsigned long long) pthread_self());
1828: fflush(stdout);
1829: }
1830:
1831: /*
1832: * var_globale_traitement_retarde_stop :
1833: * 0 -> traitement immédiat
1834: * 1 -> traitement retardé (aucun signal reçu)
1835: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
1836: */
1837:
1838: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
1839: {
1840: (*s_etat_processus).var_volatile_requete_arret = -1;
1841: }
1842: else
1843: {
1844: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
1845: }
1846: }
1847: else
1848: {
1849: // Envoi d'un signal au thread maître du groupe.
1850:
1851: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1852: {
1853: pthread_kill(thread, SIGFSTOP);
1854: deverrouillage_gestionnaire_signaux();
1855: return;
1856: }
1857: }
1858:
1859: deverrouillage_gestionnaire_signaux();
1860: return;
1861: }
1862:
1863: void
1864: interruption6(int signal, siginfo_t *siginfo, void *context)
1865: {
1866: struct_processus *s_etat_processus;
1867:
1868: verrouillage_gestionnaire_signaux();
1869:
1870: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1871: {
1872: deverrouillage_gestionnaire_signaux();
1873: return;
1874: }
1875:
1876: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1877: {
1878: printf("[%d] SIGINJECT/SIGQUIT (thread %llu)\n", (int) getpid(),
1879: (unsigned long long) pthread_self());
1880: fflush(stdout);
1881: }
1882:
1883: deverrouillage_gestionnaire_signaux();
1884: return;
1885: }
1886:
1887: void
1888: interruption7(int signal, siginfo_t *siginfo, void *context)
1889: {
1890: struct_processus *s_etat_processus;
1891:
1892: verrouillage_gestionnaire_signaux();
1893:
1894: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1895: {
1896: deverrouillage_gestionnaire_signaux();
1897: return;
1898: }
1899:
1900: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1901: {
1902: printf("[%d] SIGPIPE (thread %llu)\n", (int) getpid(),
1903: (unsigned long long) pthread_self());
1904: fflush(stdout);
1905: }
1906:
1907: (*s_etat_processus).var_volatile_requete_arret = -1;
1908: deverrouillage_gestionnaire_signaux();
1909:
1910: BUG(1, printf("[%d] SIGPIPE\n", (int) getpid()));
1911: return;
1912: }
1913:
1914: void
1915: interruption8(int signal, siginfo_t *siginfo, void *context)
1916: {
1917: pthread_t thread;
1918: struct_processus *s_etat_processus;
1919:
1920: verrouillage_gestionnaire_signaux();
1921:
1922: if ((*siginfo).si_pid == getpid())
1923: {
1924: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1925: == NULL)
1926: {
1927: deverrouillage_gestionnaire_signaux();
1928: return;
1929: }
1930:
1931: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1932: {
1933: printf("[%d] SIGURG (thread %llu)\n", (int) getpid(),
1934: (unsigned long long) pthread_self());
1935: fflush(stdout);
1936: }
1937:
1938: (*s_etat_processus).var_volatile_alarme = -1;
1939: (*s_etat_processus).var_volatile_requete_arret = -1;
1940: }
1941: else
1942: {
1943: // Envoi d'un signal au thread maître du groupe.
1944:
1945: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1946: {
1947: pthread_kill(thread, SIGURG);
1948: deverrouillage_gestionnaire_signaux();
1949: return;
1950: }
1951: }
1952:
1953: deverrouillage_gestionnaire_signaux();
1954: return;
1955: }
1956:
1957: void
1958: interruption9(int signal, siginfo_t *siginfo, void *context)
1959: {
1960: struct_processus *s_etat_processus;
1961:
1962: verrouillage_gestionnaire_signaux();
1963:
1964: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1965: {
1966: deverrouillage_gestionnaire_signaux();
1967: return;
1968: }
1969:
1970: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1971: {
1972: printf("[%d] SIGABORT/SIGPROF (thread %llu)\n", (int) getpid(),
1973: (unsigned long long) pthread_self());
1974: fflush(stdout);
1975: }
1976:
1977: pthread_kill((*s_etat_processus).tid_processus_pere, SIGFSTOP);
1978: deverrouillage_gestionnaire_signaux();
1979: return;
1980: }
1981:
1982: void
1983: interruption10(int signal, siginfo_t *siginfo, void *context)
1984: {
1985: file *fichier;
1986:
1987: struct_processus *s_etat_processus;
1988:
1989: unsigned char nom[8 + 64 + 1];
1990:
1991: verrouillage_gestionnaire_signaux();
1992:
1993: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1994: {
1995: deverrouillage_gestionnaire_signaux();
1996: return;
1997: }
1998:
1999: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
2000: (unsigned long) pthread_self());
2001:
2002: if ((fichier = fopen(nom, "w+")) != NULL)
2003: {
2004: fclose(fichier);
2005:
2006: freopen(nom, "w", stdout);
2007: freopen(nom, "w", stderr);
2008: }
2009:
2010: freopen("/dev/null", "r", stdin);
2011:
2012: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2013: {
2014: printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
2015: (unsigned long long) pthread_self());
2016: fflush(stdout);
2017: }
2018:
2019: deverrouillage_gestionnaire_signaux();
2020: return;
2021: }
2022:
2023: void
2024: traitement_exceptions_gsl(const char *reason, const char *file,
2025: int line, int gsl_errno)
2026: {
2027: struct_processus *s_etat_processus;
2028:
2029: verrouillage_gestionnaire_signaux();
2030:
2031: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2032: {
2033: deverrouillage_gestionnaire_signaux();
2034: return;
2035: }
2036:
2037: (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
2038: deverrouillage_gestionnaire_signaux();
2039: return;
2040: }
2041:
2042: // vim: ts=4