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