1: /*
2: ================================================================================
3: RPL/2 (R) version 4.0.11
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)).descripteur ==
920: (*((struct_descripteur_fichier *)
921: (*((struct_liste_chainee *) element_candidat))
922: .donnee)).descripteur) &&
923: ((*((struct_descripteur_fichier *)
924: (*((struct_liste_chainee *) element_courant))
925: .donnee)).pid ==
926: (*((struct_descripteur_fichier *)
927: (*((struct_liste_chainee *) element_candidat))
928: .donnee)).pid) && (pthread_equal(
929: (*((struct_descripteur_fichier *)
930: (*((struct_liste_chainee *) element_courant))
931: .donnee)).tid, (*((struct_descripteur_fichier *)
932: (*((struct_liste_chainee *) element_candidat))
933: .donnee)).tid) != 0))
934: {
935: break;
936: }
937:
938: element_candidat = (*((struct_liste_chainee *)
939: element_candidat)).suivant;
940: }
941:
942: if (element_candidat == NULL)
943: {
944: fclose((*((struct_descripteur_fichier *)
945: (*((struct_liste_chainee *) element_courant))
946: .donnee)).descripteur);
947: }
948:
949: free((*((struct_descripteur_fichier *)
950: (*((struct_liste_chainee *)
951: element_courant)).donnee)).nom);
952: free((struct_descripteur_fichier *)
953: (*((struct_liste_chainee *)
954: element_courant)).donnee);
955: free(element_courant);
956:
957: element_courant = element_suivant;
958: }
959:
960: element_courant = (*s_etat_processus).s_sockets;
961: while(element_courant != NULL)
962: {
963: element_suivant = (*((struct_liste_chainee *)
964: element_courant)).suivant;
965:
966: element_candidat = (*candidat).s_sockets;
967: while(element_candidat != NULL)
968: {
969: if (((*((struct_socket *)
970: (*((struct_liste_chainee *) element_courant))
971: .donnee)).socket == (*((struct_socket *)
972: (*((struct_liste_chainee *) element_candidat))
973: .donnee)).socket) &&
974: ((*((struct_socket *)
975: (*((struct_liste_chainee *) element_courant))
976: .donnee)).pid == (*((struct_socket *)
977: (*((struct_liste_chainee *) element_candidat))
978: .donnee)).pid) && (pthread_equal(
979: (*((struct_socket *)
980: (*((struct_liste_chainee *) element_courant))
981: .donnee)).tid, (*((struct_socket *)
982: (*((struct_liste_chainee *) element_candidat))
983: .donnee)).tid) != 0))
984: {
985: break;
986: }
987:
988: element_candidat = (*((struct_liste_chainee *)
989: element_candidat)).suivant;
990: }
991:
992: if (element_candidat == NULL)
993: {
994: if ((*((struct_socket *) (*((struct_liste_chainee *)
995: element_courant)).donnee)).socket_connectee
996: == d_vrai)
997: {
998: shutdown((*((struct_socket *)
999: (*((struct_liste_chainee *) element_courant))
1000: .donnee)).socket, SHUT_RDWR);
1001: }
1002:
1003: close((*((struct_socket *)
1004: (*((struct_liste_chainee *) element_courant))
1005: .donnee)).socket);
1006: }
1007:
1008: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1009: element_courant)).donnee).mutex));
1010: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1011: element_courant)).donnee).mutex));
1012:
1013: liberation(s_etat_processus,
1014: (*((struct_liste_chainee *)
1015: element_courant)).donnee);
1016: free(element_courant);
1017:
1018: element_courant = element_suivant;
1019: }
1020:
1021: element_courant = (*s_etat_processus).s_connecteurs_sql;
1022: while(element_courant != NULL)
1023: {
1024: element_suivant = (*((struct_liste_chainee *)
1025: element_courant)).suivant;
1026:
1027: element_candidat = (*candidat).s_connecteurs_sql;
1028: while(element_candidat != NULL)
1029: {
1030: if (((
1031: #ifdef MYSQL_SUPPORT
1032: ((*((struct_connecteur_sql *)
1033: (*((struct_liste_chainee *) element_courant))
1034: .donnee)).descripteur.mysql ==
1035: (*((struct_connecteur_sql *)
1036: (*((struct_liste_chainee *) element_candidat))
1037: .donnee)).descripteur.mysql)
1038: &&
1039: (strcmp((*((struct_connecteur_sql *)
1040: (*((struct_liste_chainee *) element_courant))
1041: .donnee)).type, "MYSQL") == 0)
1042: &&
1043: (strcmp((*((struct_connecteur_sql *)
1044: (*((struct_liste_chainee *) element_candidat))
1045: .donnee)).type, "MYSQL") == 0)
1046: #else
1047: 0
1048: #endif
1049: ) || (
1050: #ifdef POSTGRESQL_SUPPORT
1051: ((*((struct_connecteur_sql *)
1052: (*((struct_liste_chainee *) element_courant))
1053: .donnee)).descripteur.postgresql ==
1054: (*((struct_connecteur_sql *)
1055: (*((struct_liste_chainee *) element_candidat))
1056: .donnee)).descripteur.postgresql)
1057: &&
1058: (strcmp((*((struct_connecteur_sql *)
1059: (*((struct_liste_chainee *) element_courant))
1060: .donnee)).type, "POSTGRESQL") == 0)
1061: &&
1062: (strcmp((*((struct_connecteur_sql *)
1063: (*((struct_liste_chainee *) element_candidat))
1064: .donnee)).type, "POSTGRESQL") == 0)
1065: #else
1066: 0
1067: #endif
1068: )) &&
1069: ((*((struct_connecteur_sql *)
1070: (*((struct_liste_chainee *) element_courant))
1071: .donnee)).pid == (*((struct_connecteur_sql *)
1072: (*((struct_liste_chainee *) element_candidat))
1073: .donnee)).pid) && (pthread_equal(
1074: (*((struct_connecteur_sql *)
1075: (*((struct_liste_chainee *) element_courant))
1076: .donnee)).tid, (*((struct_connecteur_sql *)
1077: (*((struct_liste_chainee *) element_candidat))
1078: .donnee)).tid) != 0))
1079: {
1080: break;
1081: }
1082:
1083: element_candidat = (*((struct_liste_chainee *)
1084: element_candidat)).suivant;
1085: }
1086:
1087: if (element_candidat == NULL)
1088: {
1089: sqlclose((*((struct_liste_chainee *) element_courant))
1090: .donnee);
1091: }
1092:
1093: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1094: element_courant)).donnee).mutex));
1095: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1096: element_courant)).donnee).mutex));
1097:
1098: liberation(s_etat_processus, (*((struct_liste_chainee *)
1099: element_courant)).donnee);
1100: free(element_courant);
1101:
1102: element_courant = element_suivant;
1103: }
1104:
1105: element_courant = (*s_etat_processus).s_marques;
1106: while(element_courant != NULL)
1107: {
1108: free((*((struct_marque *) element_courant)).label);
1109: free((*((struct_marque *) element_courant)).position);
1110: element_suivant = (*((struct_marque *) element_courant))
1111: .suivant;
1112: free(element_courant);
1113: element_courant = element_suivant;
1114: }
1115:
1116: liberation_allocateur(s_etat_processus);
1117:
1118: sem_post(&((*s_etat_processus).semaphore_fork));
1119: sem_destroy(&((*s_etat_processus).semaphore_fork));
1120:
1121: free(s_etat_processus);
1122:
1123: s_etat_processus = candidat;
1124: }
1125:
1126: l_element_suivant = (*l_element_courant).suivant;
1127:
1128: free((struct_thread *) (*l_element_courant).donnee);
1129: free((struct_liste_chainee *) l_element_courant);
1130:
1131: l_element_courant = l_element_suivant;
1132: }
1133:
1134: liste_threads = NULL;
1135:
1136: l_element_courant = liste_threads_surveillance;
1137:
1138: while(l_element_courant != NULL)
1139: {
1140: s_argument_thread = (struct_descripteur_thread *)
1141: (*l_element_courant).donnee;
1142:
1143: close((*s_argument_thread).pipe_objets[0]);
1144: close((*s_argument_thread).pipe_acquittement[1]);
1145: close((*s_argument_thread).pipe_injections[1]);
1146: close((*s_argument_thread).pipe_nombre_injections[1]);
1147: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
1148: close((*s_argument_thread).pipe_interruptions[0]);
1149: close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
1150:
1151: if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
1152: {
1153: (*s_etat_processus).erreur_systeme = d_es_processus;
1154: return;
1155: }
1156:
1157: (*s_argument_thread).nombre_references--;
1158:
1159: BUG((*s_argument_thread).nombre_references < 0,
1160: printf("(*s_argument_thread).nombre_references = %d\n",
1161: (int) (*s_argument_thread).nombre_references));
1162:
1163: if ((*s_argument_thread).nombre_references == 0)
1164: {
1165: if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
1166: {
1167: (*s_etat_processus).erreur_systeme = d_es_processus;
1168: return;
1169: }
1170:
1171: pthread_mutex_destroy(&((*s_argument_thread).mutex));
1172: free(s_argument_thread);
1173: }
1174: else
1175: {
1176: if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
1177: {
1178: (*s_etat_processus).erreur_systeme = d_es_processus;
1179: return;
1180: }
1181: }
1182:
1183: l_element_suivant = (*l_element_courant).suivant;
1184: free((struct_liste_chainee *) l_element_courant);
1185: l_element_courant = l_element_suivant;
1186: }
1187:
1188: liste_threads_surveillance = NULL;
1189:
1190: if (sem_post(&semaphore_liste_threads) != 0)
1191: {
1192: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1193: (*s_etat_processus).erreur_systeme = d_es_processus;
1194: return;
1195: }
1196:
1197: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1198: sigpending(&set);
1199: return;
1200: }
1201:
1202: static struct_processus *
1203: recherche_thread(pid_t pid, pthread_t tid)
1204: {
1205: volatile struct_liste_chainee_volatile *l_element_courant;
1206:
1207: struct_processus *s_etat_processus;
1208:
1209: l_element_courant = liste_threads;
1210:
1211: while(l_element_courant != NULL)
1212: {
1213: if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
1214: .tid, tid) != 0) && ((*((struct_thread *)
1215: (*l_element_courant).donnee)).pid == pid))
1216: {
1217: break;
1218: }
1219:
1220: l_element_courant = (*l_element_courant).suivant;
1221: }
1222:
1223: if (l_element_courant == NULL)
1224: {
1225: /*
1226: * Le processus n'existe plus. On ne distribue aucun signal.
1227: */
1228:
1229: return(NULL);
1230: }
1231:
1232: s_etat_processus = (*((struct_thread *)
1233: (*l_element_courant).donnee)).s_etat_processus;
1234:
1235: return(s_etat_processus);
1236: }
1237:
1238: static logical1
1239: recherche_thread_principal(pid_t pid, pthread_t *thread)
1240: {
1241: volatile struct_liste_chainee_volatile *l_element_courant;
1242:
1243: l_element_courant = liste_threads;
1244:
1245: while(l_element_courant != NULL)
1246: {
1247: if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
1248: == d_vrai) && ((*((struct_thread *)
1249: (*l_element_courant).donnee)).pid == pid))
1250: {
1251: break;
1252: }
1253:
1254: l_element_courant = (*l_element_courant).suivant;
1255: }
1256:
1257: if (l_element_courant == NULL)
1258: {
1259: /*
1260: * Le processus n'existe plus. On ne distribue aucun signal.
1261: */
1262:
1263: return(d_faux);
1264: }
1265:
1266: (*thread) = (*((struct_thread *) (*l_element_courant).donnee)).tid;
1267:
1268: return(d_vrai);
1269: }
1270:
1271:
1272: /*
1273: ================================================================================
1274: Procédures de gestion des signaux d'interruption
1275: ================================================================================
1276: Entrée : variable globale
1277: --------------------------------------------------------------------------------
1278: Sortie : variable globale modifiée
1279: --------------------------------------------------------------------------------
1280: Effets de bord : néant
1281: ================================================================================
1282: */
1283:
1284: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
1285: // des signaux asynchrones. Elles de doivent pas bloquer dans le cas où
1286: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
1287:
1288: static inline void
1289: verrouillage_gestionnaire_signaux()
1290: {
1291: int semaphore;
1292:
1293: sigset_t oldset;
1294: sigset_t set;
1295:
1296: sem_t *sem;
1297:
1298: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1299: != NULL)
1300: {
1301: if (sem_post(sem) != 0)
1302: {
1303: BUG(1, uprintf("Lock error !\n"));
1304: return;
1305: }
1306: }
1307:
1308: // Il faut respecteur l'atomicité des deux opérations suivantes !
1309:
1310: sigfillset(&set);
1311: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1312:
1313: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1314: {
1315: if (errno != EINTR)
1316: {
1317: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1318: BUG(1, uprintf("Unlock error !\n"));
1319: return;
1320: }
1321: }
1322:
1323: if (sem_post(&semaphore_gestionnaires_signaux) == -1)
1324: {
1325: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1326: BUG(1, uprintf("Lock error !\n"));
1327: return;
1328: }
1329:
1330: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1331: {
1332: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1333: BUG(1, uprintf("Lock error !\n"));
1334: return;
1335: }
1336:
1337: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1338: {
1339: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1340: BUG(1, uprintf("Unlock error !\n"));
1341: return;
1342: }
1343:
1344: if (semaphore == 1)
1345: {
1346: // Le semaphore ne peut être pris par le thread qui a appelé
1347: // le gestionnaire de signal car le signal est bloqué par ce thread
1348: // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
1349: // par un thread concurrent. On essaye donc de le bloquer jusqu'à
1350: // ce que ce soit possible.
1351:
1352: while(sem_trywait(&semaphore_liste_threads) == -1)
1353: {
1354: if ((errno != EINTR) && (errno != EAGAIN))
1355: {
1356: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1357:
1358: while(sem_wait(sem) == -1)
1359: {
1360: if (errno != EINTR)
1361: {
1362: BUG(1, uprintf("Lock error !\n"));
1363: return;
1364: }
1365: }
1366:
1367: BUG(1, uprintf("Lock error !\n"));
1368: return;
1369: }
1370:
1371: sched_yield();
1372: }
1373: }
1374:
1375: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1376: sigpending(&set);
1377:
1378: return;
1379: }
1380:
1381: static inline void
1382: deverrouillage_gestionnaire_signaux()
1383: {
1384: int semaphore;
1385:
1386: sem_t *sem;
1387:
1388: sigset_t oldset;
1389: sigset_t set;
1390:
1391: // Il faut respecteur l'atomicité des deux opérations suivantes !
1392:
1393: sigfillset(&set);
1394: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1395:
1396: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1397: {
1398: if (errno != EINTR)
1399: {
1400: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1401: BUG(1, uprintf("Unlock error !\n"));
1402: return;
1403: }
1404: }
1405:
1406: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1407: {
1408: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1409: BUG(1, uprintf("Unlock error !\n"));
1410: return;
1411: }
1412:
1413: while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1414: {
1415: if (errno != EINTR)
1416: {
1417: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1418: BUG(1, uprintf("Unlock error !\n"));
1419: return;
1420: }
1421: }
1422:
1423: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1424: {
1425: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1426: BUG(1, uprintf("Unlock error !\n"));
1427: return;
1428: }
1429:
1430: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1431: != NULL)
1432: {
1433: while(sem_wait(sem) == -1)
1434: {
1435: if (errno != EINTR)
1436: {
1437: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1438: BUG(1, uprintf("Unlock error !\n"));
1439: return;
1440: }
1441: }
1442: }
1443:
1444: if (semaphore == 1)
1445: {
1446: if (sem_post(&semaphore_liste_threads) != 0)
1447: {
1448: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1449:
1450: BUG(1, uprintf("Unlock error !\n"));
1451: return;
1452: }
1453: }
1454:
1455: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1456: sigpending(&set);
1457:
1458: return;
1459: }
1460:
1461: void
1462: interruption1(int signal, siginfo_t *siginfo, void *context)
1463: {
1464: pthread_t thread;
1465:
1466: struct_processus *s_etat_processus;
1467:
1468: volatile sig_atomic_t exclusion = 0;
1469:
1470: verrouillage_gestionnaire_signaux();
1471:
1472: switch(signal)
1473: {
1474: case SIGALRM :
1475: {
1476: if ((*siginfo).si_pid == getpid())
1477: {
1478: if ((s_etat_processus = recherche_thread(getpid(),
1479: pthread_self())) == NULL)
1480: {
1481: deverrouillage_gestionnaire_signaux();
1482: return;
1483: }
1484:
1485: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1486: {
1487: printf("[%d] SIGALRM (thread %llu)\n", (int) getpid(),
1488: (unsigned long long) pthread_self());
1489: fflush(stdout);
1490: }
1491:
1492: if ((*s_etat_processus).pid_processus_pere != getpid())
1493: {
1494: kill((*s_etat_processus).pid_processus_pere, signal);
1495: }
1496: else
1497: {
1498: (*s_etat_processus).var_volatile_alarme = -1;
1499: (*s_etat_processus).var_volatile_requete_arret = -1;
1500: }
1501: }
1502: else
1503: {
1504: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1505: {
1506: pthread_kill(thread, signal);
1507: }
1508: }
1509:
1510: break;
1511: }
1512:
1513: case SIGINT :
1514: {
1515: /*
1516: * Une vieille spécification POSIX permet au pointeur siginfo
1517: * d'être nul dans le cas d'un ^C envoyé depuis le clavier.
1518: * Solaris suit en particulier cette spécification.
1519: */
1520:
1521: if (siginfo == NULL)
1522: {
1523: kill(getpid(), signal);
1524: }
1525: else if ((*siginfo).si_pid == getpid())
1526: {
1527: if ((s_etat_processus = recherche_thread(getpid(),
1528: pthread_self())) == NULL)
1529: {
1530: deverrouillage_gestionnaire_signaux();
1531: return;
1532: }
1533:
1534: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1535: {
1536: printf("[%d] SIGINT (thread %llu)\n", (int) getpid(),
1537: (unsigned long long) pthread_self());
1538: fflush(stdout);
1539: }
1540:
1541: if ((*s_etat_processus).pid_processus_pere != getpid())
1542: {
1543: kill((*s_etat_processus).pid_processus_pere, signal);
1544: }
1545: else
1546: {
1547: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1548:
1549: while(exclusion == 1);
1550: exclusion = 1;
1551:
1552: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1553: {
1554: deverrouillage_gestionnaire_signaux();
1555: exclusion = 0;
1556: return;
1557: }
1558:
1559: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1560: {
1561: printf("+++Interruption\n");
1562: }
1563: else
1564: {
1565: printf("+++Interrupt\n");
1566: }
1567:
1568: fflush(stdout);
1569:
1570: (*s_etat_processus).var_volatile_requete_arret = -1;
1571: (*s_etat_processus).var_volatile_alarme = -1;
1572:
1573: exclusion = 0;
1574: }
1575: }
1576: else
1577: {
1578: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1579: {
1580: pthread_kill(thread, signal);
1581: }
1582: }
1583:
1584: break;
1585: }
1586:
1587: default :
1588: {
1589: BUG(1, uprintf("[%d] Unknown signal %d in this context\n",
1590: (int) getpid(), signal));
1591: break;
1592: }
1593: }
1594:
1595: deverrouillage_gestionnaire_signaux();
1596: return;
1597: }
1598:
1599: void
1600: interruption2(int signal, siginfo_t *siginfo, void *context)
1601: {
1602: pthread_t thread;
1603: struct_processus *s_etat_processus;
1604:
1605: verrouillage_gestionnaire_signaux();
1606:
1607: if (siginfo == NULL)
1608: {
1609: /*
1610: * Le signal SIGFSTP provient de la mort du processus de contrôle.
1611: * Sous certains systèmes (Linux...), la mort du terminal de contrôle
1612: * se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
1613: * (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
1614: * non initialisée (pointeur NULL) issue de TERMIO.
1615: */
1616:
1617: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1618: {
1619: pthread_kill(thread, SIGHUP);
1620: deverrouillage_gestionnaire_signaux();
1621: return;
1622: }
1623: }
1624: else if ((*siginfo).si_pid == getpid())
1625: {
1626: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1627: == NULL)
1628: {
1629: deverrouillage_gestionnaire_signaux();
1630: return;
1631: }
1632:
1633: /*
1634: * 0 => fonctionnement normal
1635: * -1 => requête
1636: * 1 => requête acceptée en attente de traitement
1637: */
1638:
1639: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1640: {
1641: printf("[%d] SIGTSTP (thread %llu)\n", (int) getpid(),
1642: (unsigned long long) pthread_self());
1643: fflush(stdout);
1644: }
1645:
1646: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1647: {
1648: kill((*s_etat_processus).pid_processus_pere, signal);
1649: }
1650: else
1651: {
1652: (*s_etat_processus).var_volatile_requete_arret2 = -1;
1653: }
1654: }
1655: else
1656: {
1657: // Envoi d'un signal au thread maître du groupe.
1658:
1659: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1660: {
1661: pthread_kill(thread, SIGTSTP);
1662: deverrouillage_gestionnaire_signaux();
1663: return;
1664: }
1665: }
1666:
1667: deverrouillage_gestionnaire_signaux();
1668: return;
1669: }
1670:
1671: void
1672: interruption3(int signal, siginfo_t *siginfo, void *context)
1673: {
1674: struct_processus *s_etat_processus;
1675:
1676: static int compteur = 0;
1677:
1678: verrouillage_gestionnaire_signaux();
1679:
1680: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1681: {
1682: deverrouillage_gestionnaire_signaux();
1683: return;
1684: }
1685:
1686: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1687: {
1688: printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
1689: (unsigned long long) pthread_self());
1690: fflush(stdout);
1691: }
1692:
1693: if ((*s_etat_processus).var_volatile_recursivite == -1)
1694: {
1695: // Segfault dans un appel de fonction récursive
1696: deverrouillage_gestionnaire_signaux();
1697: longjmp(contexte, -1);
1698: }
1699: else
1700: {
1701: // Segfault dans une routine interne
1702: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1703: {
1704: printf("+++Système : Violation d'accès (dépassement de pile)\n");
1705: }
1706: else
1707: {
1708: printf("+++System : Access violation (stack overflow)\n");
1709: }
1710:
1711: fflush(stdout);
1712:
1713: compteur++;
1714:
1715: if (compteur > 1)
1716: {
1717: deverrouillage_gestionnaire_signaux();
1718: exit(EXIT_FAILURE);
1719: }
1720: else
1721: {
1722: deverrouillage_gestionnaire_signaux();
1723: longjmp(contexte_initial, -1);
1724: }
1725: }
1726:
1727: deverrouillage_gestionnaire_signaux();
1728: return;
1729: }
1730:
1731: void
1732: interruption4(int signal, siginfo_t *siginfo, void *context)
1733: {
1734: struct_processus *s_etat_processus;
1735:
1736: verrouillage_gestionnaire_signaux();
1737:
1738: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1739: {
1740: deverrouillage_gestionnaire_signaux();
1741: return;
1742: }
1743:
1744: /*
1745: * Démarrage d'un processus fils ou gestion de SIGCONT (SUSPEND)
1746: */
1747:
1748: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1749: {
1750: printf("[%d] SIGSTART/SIGCONT (thread %llu)\n", (int) getpid(),
1751: (unsigned long long) pthread_self());
1752: fflush(stdout);
1753: }
1754:
1755: deverrouillage_gestionnaire_signaux();
1756: return;
1757: }
1758:
1759: void
1760: interruption5(int signal, siginfo_t *siginfo, void *context)
1761: {
1762: pthread_t thread;
1763: struct_processus *s_etat_processus;
1764:
1765: verrouillage_gestionnaire_signaux();
1766:
1767: if ((*siginfo).si_pid == getpid())
1768: {
1769: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1770: == NULL)
1771: {
1772: deverrouillage_gestionnaire_signaux();
1773: return;
1774: }
1775:
1776: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1777: {
1778: printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(),
1779: (unsigned long long) pthread_self());
1780: fflush(stdout);
1781: }
1782:
1783: /*
1784: * var_globale_traitement_retarde_stop :
1785: * 0 -> traitement immédiat
1786: * 1 -> traitement retardé (aucun signal reçu)
1787: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
1788: */
1789:
1790: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
1791: {
1792: (*s_etat_processus).var_volatile_requete_arret = -1;
1793: }
1794: else
1795: {
1796: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
1797: }
1798: }
1799: else
1800: {
1801: // Envoi d'un signal au thread maître du groupe.
1802:
1803: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1804: {
1805: pthread_kill(thread, SIGFSTOP);
1806: deverrouillage_gestionnaire_signaux();
1807: return;
1808: }
1809: }
1810:
1811: deverrouillage_gestionnaire_signaux();
1812: return;
1813: }
1814:
1815: void
1816: interruption6(int signal, siginfo_t *siginfo, void *context)
1817: {
1818: struct_processus *s_etat_processus;
1819:
1820: verrouillage_gestionnaire_signaux();
1821:
1822: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1823: {
1824: deverrouillage_gestionnaire_signaux();
1825: return;
1826: }
1827:
1828: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1829: {
1830: printf("[%d] SIGINJECT/SIGQUIT (thread %llu)\n", (int) getpid(),
1831: (unsigned long long) pthread_self());
1832: fflush(stdout);
1833: }
1834:
1835: deverrouillage_gestionnaire_signaux();
1836: return;
1837: }
1838:
1839: void
1840: interruption7(int signal, siginfo_t *siginfo, void *context)
1841: {
1842: struct_processus *s_etat_processus;
1843:
1844: verrouillage_gestionnaire_signaux();
1845:
1846: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1847: {
1848: deverrouillage_gestionnaire_signaux();
1849: return;
1850: }
1851:
1852: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1853: {
1854: printf("[%d] SIGPIPE (thread %llu)\n", (int) getpid(),
1855: (unsigned long long) pthread_self());
1856: fflush(stdout);
1857: }
1858:
1859: (*s_etat_processus).var_volatile_requete_arret = -1;
1860: deverrouillage_gestionnaire_signaux();
1861:
1862: BUG(1, printf("[%d] SIGPIPE\n", (int) getpid()));
1863: return;
1864: }
1865:
1866: void
1867: interruption8(int signal, siginfo_t *siginfo, void *context)
1868: {
1869: pthread_t thread;
1870: struct_processus *s_etat_processus;
1871:
1872: verrouillage_gestionnaire_signaux();
1873:
1874: if ((*siginfo).si_pid == getpid())
1875: {
1876: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1877: == NULL)
1878: {
1879: deverrouillage_gestionnaire_signaux();
1880: return;
1881: }
1882:
1883: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1884: {
1885: printf("[%d] SIGURG (thread %llu)\n", (int) getpid(),
1886: (unsigned long long) pthread_self());
1887: fflush(stdout);
1888: }
1889:
1890: (*s_etat_processus).var_volatile_alarme = -1;
1891: (*s_etat_processus).var_volatile_requete_arret = -1;
1892: }
1893: else
1894: {
1895: // Envoi d'un signal au thread maître du groupe.
1896:
1897: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1898: {
1899: pthread_kill(thread, SIGURG);
1900: deverrouillage_gestionnaire_signaux();
1901: return;
1902: }
1903: }
1904:
1905: deverrouillage_gestionnaire_signaux();
1906: return;
1907: }
1908:
1909: void
1910: interruption9(int signal, siginfo_t *siginfo, void *context)
1911: {
1912: struct_processus *s_etat_processus;
1913:
1914: verrouillage_gestionnaire_signaux();
1915:
1916: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1917: {
1918: deverrouillage_gestionnaire_signaux();
1919: return;
1920: }
1921:
1922: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1923: {
1924: printf("[%d] SIGABORT/SIGPROF (thread %llu)\n", (int) getpid(),
1925: (unsigned long long) pthread_self());
1926: fflush(stdout);
1927: }
1928:
1929: pthread_kill((*s_etat_processus).tid_processus_pere, SIGFSTOP);
1930: deverrouillage_gestionnaire_signaux();
1931: return;
1932: }
1933:
1934: void
1935: interruption10(int signal, siginfo_t *siginfo, void *context)
1936: {
1937: file *fichier;
1938:
1939: struct_processus *s_etat_processus;
1940:
1941: unsigned char nom[8 + 64 + 1];
1942:
1943: verrouillage_gestionnaire_signaux();
1944:
1945: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1946: {
1947: deverrouillage_gestionnaire_signaux();
1948: return;
1949: }
1950:
1951: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
1952: (unsigned long) pthread_self());
1953:
1954: if ((fichier = fopen(nom, "w+")) != NULL)
1955: {
1956: fclose(fichier);
1957:
1958: freopen(nom, "w", stdout);
1959: freopen(nom, "w", stderr);
1960: }
1961:
1962: freopen("/dev/null", "r", stdin);
1963:
1964: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1965: {
1966: printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
1967: (unsigned long long) pthread_self());
1968: fflush(stdout);
1969: }
1970:
1971: deverrouillage_gestionnaire_signaux();
1972: return;
1973: }
1974:
1975: void
1976: traitement_exceptions_gsl(const char *reason, const char *file,
1977: int line, int gsl_errno)
1978: {
1979: struct_processus *s_etat_processus;
1980:
1981: verrouillage_gestionnaire_signaux();
1982:
1983: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1984: {
1985: deverrouillage_gestionnaire_signaux();
1986: return;
1987: }
1988:
1989: (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
1990: deverrouillage_gestionnaire_signaux();
1991: return;
1992: }
1993:
1994: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>