Annotation of rpl/src/interruptions.c, revision 1.85
1.1 bertrand 1: /*
2: ================================================================================
1.82 bertrand 3: RPL/2 (R) version 4.1.4
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);
1.80 bertrand 1128: sem_close((*s_etat_processus).semaphore_fork);
1.79 bertrand 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.80 bertrand 1391: # ifndef SEMAPHORES_NOMMES
1.77 bertrand 1392: sem_wait(&((*s_etat_processus).semaphore_fork));
1.80 bertrand 1393: # else
1394: sem_wait((*s_etat_processus).semaphore_fork);
1395: # endif
1.68 bertrand 1396: BUG(1, uprintf("Lock error !\n"));
1397: return;
1.1 bertrand 1398: }
1399: }
1400:
1401: return;
1402: }
1403:
1404: static inline void
1.68 bertrand 1405: deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
1.1 bertrand 1406: {
1407: int semaphore;
1408:
1409: // Il faut respecteur l'atomicité des deux opérations suivantes !
1410:
1.68 bertrand 1411: if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) == -1)
1.1 bertrand 1412: {
1.79 bertrand 1413: # ifndef SEMAPHORES_NOMMES
1.77 bertrand 1414: sem_wait(&((*s_etat_processus).semaphore_fork));
1.79 bertrand 1415: # else
1416: sem_wait((*s_etat_processus).semaphore_fork);
1417: # endif
1.68 bertrand 1418: BUG(1, uprintf("Unlock error !\n"));
1419: return;
1.1 bertrand 1420: }
1421:
1.8 bertrand 1422: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1423: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1.8 bertrand 1424: # else
1425: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1426: # endif
1.1 bertrand 1427: {
1.79 bertrand 1428: # ifndef SEMAPHORES_NOMMES
1.77 bertrand 1429: sem_wait(&((*s_etat_processus).semaphore_fork));
1.79 bertrand 1430: # else
1431: sem_wait((*s_etat_processus).semaphore_fork);
1432: # endif
1.1 bertrand 1433: BUG(1, uprintf("Unlock error !\n"));
1434: return;
1435: }
1436:
1.8 bertrand 1437: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1438: while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1.8 bertrand 1439: # else
1440: while(sem_wait(semaphore_gestionnaires_signaux) == -1)
1441: # endif
1.1 bertrand 1442: {
1443: if (errno != EINTR)
1444: {
1.79 bertrand 1445: # ifndef SEMAPHORES_NOMMES
1.77 bertrand 1446: sem_wait(&((*s_etat_processus).semaphore_fork));
1.79 bertrand 1447: # else
1448: sem_wait((*s_etat_processus).semaphore_fork);
1449: # endif
1.1 bertrand 1450: BUG(1, uprintf("Unlock error !\n"));
1451: return;
1452: }
1453: }
1454:
1.68 bertrand 1455: if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
1.1 bertrand 1456: {
1.79 bertrand 1457: # ifndef SEMAPHORES_NOMMES
1.77 bertrand 1458: sem_wait(&((*s_etat_processus).semaphore_fork));
1.79 bertrand 1459: # else
1460: sem_wait((*s_etat_processus).semaphore_fork);
1461: # endif
1.1 bertrand 1462: BUG(1, uprintf("Unlock error !\n"));
1463: return;
1464: }
1465:
1.79 bertrand 1466: # ifndef SEMAPHORES_NOMMES
1.78 bertrand 1467: while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
1.79 bertrand 1468: # else
1469: while(sem_wait((*s_etat_processus).semaphore_fork) != 0)
1470: # endif
1.1 bertrand 1471: {
1.79 bertrand 1472: if (errno != EINTR)
1473: {
1474: BUG(1, uprintf("Unlock error !\n"));
1475: return;
1476: }
1.1 bertrand 1477: }
1478:
1479: if (semaphore == 1)
1480: {
1.68 bertrand 1481: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1 bertrand 1482: {
1483: BUG(1, uprintf("Unlock error !\n"));
1484: return;
1485: }
1486: }
1487:
1488: return;
1489: }
1490:
1.65 bertrand 1491: #define test_signal(signal) \
1.67 bertrand 1492: if (signal_test == SIGTEST) { signal_test = signal; return; }
1.66 bertrand 1493:
1.67 bertrand 1494: // Récupération des signaux
1495: // - SIGINT (arrêt au clavier)
1496: // - SIGTERM (signal d'arrêt en provenance du système)
1.65 bertrand 1497:
1.67 bertrand 1498: void
1499: interruption1(int signal)
1.30 bertrand 1500: {
1.67 bertrand 1501: test_signal(signal);
1.30 bertrand 1502:
1.67 bertrand 1503: switch(signal)
1.31 bertrand 1504: {
1.67 bertrand 1505: case SIGINT:
1506: envoi_signal_processus(getpid(), rpl_sigint);
1507: break;
1.66 bertrand 1508:
1.67 bertrand 1509: case SIGTERM:
1510: envoi_signal_processus(getpid(), rpl_sigterm);
1511: break;
1.31 bertrand 1512:
1.81 bertrand 1513: case SIGUSR1:
1.67 bertrand 1514: envoi_signal_processus(getpid(), rpl_sigalrm);
1515: break;
1.31 bertrand 1516: }
1.66 bertrand 1517:
1.67 bertrand 1518: return;
1.66 bertrand 1519: }
1520:
1.67 bertrand 1521: inline static void
1522: signal_alrm(struct_processus *s_etat_processus, pid_t pid)
1.66 bertrand 1523: {
1.67 bertrand 1524: struct_processus *s_thread_principal;
1.66 bertrand 1525:
1.68 bertrand 1526: verrouillage_gestionnaire_signaux(s_etat_processus);
1.67 bertrand 1527:
1528: if (pid == getpid())
1529: {
1530: // Si pid est égal à getpid(), le signal à traiter est issu
1531: // du même processus que celui qui va le traiter, mais d'un thread
1532: // différent.
1.66 bertrand 1533:
1.67 bertrand 1534: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1.66 bertrand 1535: {
1.67 bertrand 1536: printf("[%d] RPL/SIGALRM (thread %llu)\n", (int) getpid(),
1537: (unsigned long long) pthread_self());
1538: fflush(stdout);
1539: }
1.66 bertrand 1540:
1.67 bertrand 1541: if ((*s_etat_processus).pid_processus_pere != getpid())
1542: {
1543: // On n'est pas dans le processus père, on remonte le signal.
1544: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1545: rpl_sigalrm);
1.66 bertrand 1546: }
1547: else
1548: {
1.67 bertrand 1549: // On est dans le processus père, on effectue un arrêt d'urgence.
1550: (*s_etat_processus).var_volatile_alarme = -1;
1551: (*s_etat_processus).var_volatile_requete_arret = -1;
1.66 bertrand 1552: }
1.67 bertrand 1553: }
1554: else
1555: {
1556: // Le signal est issu d'un processus différent. On recherche le
1557: // thread principal pour remonter le signal.
1.66 bertrand 1558:
1.67 bertrand 1559: if ((s_thread_principal = recherche_thread_principal(getpid()))
1560: != NULL)
1.66 bertrand 1561: {
1.67 bertrand 1562: envoi_signal_contexte(s_thread_principal, rpl_sigalrm);
1.66 bertrand 1563: }
1.67 bertrand 1564: }
1.29 bertrand 1565:
1.68 bertrand 1566: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.66 bertrand 1567: return;
1568: }
1569:
1.67 bertrand 1570: inline static void
1571: signal_term(struct_processus *s_etat_processus, pid_t pid)
1.66 bertrand 1572: {
1.67 bertrand 1573: struct_processus *s_thread_principal;
1.66 bertrand 1574: volatile sig_atomic_t exclusion = 0;
1575:
1.68 bertrand 1576: verrouillage_gestionnaire_signaux(s_etat_processus);
1.66 bertrand 1577:
1.67 bertrand 1578: if (pid == getpid())
1.1 bertrand 1579: {
1.67 bertrand 1580: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1581: {
1582: printf("[%d] RPL/SIGTERM (thread %llu)\n", (int) getpid(),
1583: (unsigned long long) pthread_self());
1584: fflush(stdout);
1585: }
1586:
1587: if ((*s_etat_processus).pid_processus_pere != getpid())
1588: {
1589: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1590: rpl_sigterm);
1591: }
1592: else
1.1 bertrand 1593: {
1.67 bertrand 1594: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1595:
1596: while(exclusion == 1);
1597: exclusion = 1;
1.1 bertrand 1598:
1.67 bertrand 1599: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1.1 bertrand 1600: {
1.68 bertrand 1601: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67 bertrand 1602: exclusion = 0;
1603: return;
1.1 bertrand 1604: }
1605:
1.67 bertrand 1606: (*s_etat_processus).var_volatile_requete_arret = -1;
1607: (*s_etat_processus).var_volatile_alarme = -1;
1608:
1609: exclusion = 0;
1.1 bertrand 1610: }
1.67 bertrand 1611: }
1612: else
1613: {
1614: if ((s_thread_principal = recherche_thread_principal(getpid()))
1615: != NULL)
1.1 bertrand 1616: {
1.67 bertrand 1617: envoi_signal_contexte(s_thread_principal, rpl_sigterm);
1618: }
1619: }
1.44 bertrand 1620:
1.68 bertrand 1621: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67 bertrand 1622: return;
1623: }
1.1 bertrand 1624:
1.67 bertrand 1625: inline static void
1626: signal_int(struct_processus *s_etat_processus, pid_t pid)
1627: {
1628: struct_processus *s_thread_principal;
1629: volatile sig_atomic_t exclusion = 0;
1.1 bertrand 1630:
1.68 bertrand 1631: verrouillage_gestionnaire_signaux(s_etat_processus);
1.1 bertrand 1632:
1.67 bertrand 1633: if (pid == getpid())
1634: {
1635: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1636: {
1637: printf("[%d] RPL/SIGINT (thread %llu)\n", (int) getpid(),
1638: (unsigned long long) pthread_self());
1639: fflush(stdout);
1640: }
1.1 bertrand 1641:
1.67 bertrand 1642: if ((*s_etat_processus).pid_processus_pere != getpid())
1643: {
1644: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1645: rpl_sigint);
1646: }
1647: else
1648: {
1649: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1.44 bertrand 1650:
1.67 bertrand 1651: while(exclusion == 1);
1652: exclusion = 1;
1.1 bertrand 1653:
1.67 bertrand 1654: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1655: {
1.68 bertrand 1656: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67 bertrand 1657: exclusion = 0;
1658: return;
1659: }
1.1 bertrand 1660:
1.67 bertrand 1661: if ((*s_etat_processus).langue == 'F')
1662: {
1663: printf("+++Interruption\n");
1.1 bertrand 1664: }
1665: else
1666: {
1.67 bertrand 1667: printf("+++Interrupt\n");
1.1 bertrand 1668: }
1669:
1.67 bertrand 1670: fflush(stdout);
1671:
1672: (*s_etat_processus).var_volatile_requete_arret = -1;
1673: (*s_etat_processus).var_volatile_alarme = -1;
1674:
1675: exclusion = 0;
1.1 bertrand 1676: }
1.67 bertrand 1677: }
1678: else
1679: {
1680: if ((s_thread_principal = recherche_thread_principal(getpid()))
1681: != NULL)
1.1 bertrand 1682: {
1.67 bertrand 1683: envoi_signal_contexte(s_thread_principal, rpl_sigint);
1.1 bertrand 1684: }
1685: }
1686:
1.68 bertrand 1687: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1 bertrand 1688: return;
1689: }
1690:
1.67 bertrand 1691: // Récupération des signaux
1692: // - SIGFSTP
1693: //
1694: // ATTENTION :
1695: // Le signal SIGFSTP provient de la mort du processus de contrôle.
1696: // Sous certains systèmes (Linux...), la mort du terminal de contrôle
1697: // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
1698: // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
1699: // non initialisée (pointeur NULL) issue de TERMIO.
1700:
1.1 bertrand 1701: void
1.67 bertrand 1702: interruption2(int signal)
1.1 bertrand 1703: {
1.65 bertrand 1704: test_signal(signal);
1.67 bertrand 1705: envoi_signal_processus(getpid(), rpl_sigtstp);
1.66 bertrand 1706: return;
1707: }
1708:
1.67 bertrand 1709: static inline void
1710: signal_tstp(struct_processus *s_etat_processus, pid_t pid)
1.66 bertrand 1711: {
1712: struct_processus *s_thread_principal;
1713:
1.68 bertrand 1714: verrouillage_gestionnaire_signaux(s_etat_processus);
1.1 bertrand 1715:
1.30 bertrand 1716: if (pid == getpid())
1.1 bertrand 1717: {
1718: /*
1719: * 0 => fonctionnement normal
1720: * -1 => requête
1721: * 1 => requête acceptée en attente de traitement
1722: */
1723:
1724: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1725: {
1.67 bertrand 1726: printf("[%d] RPL/SIGTSTP (thread %llu)\n", (int) getpid(),
1.1 bertrand 1727: (unsigned long long) pthread_self());
1728: fflush(stdout);
1729: }
1730:
1731: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1732: {
1.67 bertrand 1733: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1734: rpl_sigtstp);
1.1 bertrand 1735: }
1736: else
1737: {
1738: (*s_etat_processus).var_volatile_requete_arret2 = -1;
1739: }
1740: }
1741: else
1742: {
1743: // Envoi d'un signal au thread maître du groupe.
1744:
1.66 bertrand 1745: if ((s_thread_principal = recherche_thread_principal(getpid()))
1746: != NULL)
1.1 bertrand 1747: {
1.67 bertrand 1748: envoi_signal_contexte(s_thread_principal, rpl_sigtstp);
1.1 bertrand 1749: }
1750: }
1751:
1.68 bertrand 1752: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1 bertrand 1753: return;
1754: }
1755:
1756: void
1.67 bertrand 1757: interruption3(int signal)
1.1 bertrand 1758: {
1.66 bertrand 1759: // Si on passe par ici, c'est qu'il est impossible de récupérer
1760: // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
1761: // ce qu'il reste des processus orphelins.
1762:
1.85 ! bertrand 1763: int ios;
! 1764:
1.81 bertrand 1765: unsigned char message_1[] = "+++System : Uncaught access violation\n"
1766: "+++System : Aborting !\n";
1767: unsigned char message_2[] = "+++System : Stack overflow\n"
1.67 bertrand 1768: "+++System : Aborting !\n";
1769:
1770: test_signal(signal);
1.66 bertrand 1771:
1772: if (pid_processus_pere == getpid())
1773: {
1.81 bertrand 1774: kill(pid_processus_pere, SIGUSR1);
1775: }
1776:
1777:
1778: if (signal != SIGUSR2)
1779: {
1.85 ! bertrand 1780: ios = write(STDERR_FILENO, message_1, strlen(message_1));
1.81 bertrand 1781: }
1782: else
1783: {
1.85 ! bertrand 1784: ios = write(STDERR_FILENO, message_2, strlen(message_2));
1.66 bertrand 1785: }
1786:
1787: _exit(EXIT_FAILURE);
1788: }
1789:
1.81 bertrand 1790:
1791: static void
1792: sortie_interruption_depassement_pile(void *arg1, void *arg2, void *arg3)
1.66 bertrand 1793: {
1.81 bertrand 1794: switch((*((volatile int *) arg1)))
1795: {
1796: case 1:
1797: longjmp(contexte_ecriture, -1);
1798: break;
1.63 bertrand 1799:
1.81 bertrand 1800: case 2:
1801: longjmp(contexte_impression, -1);
1802: break;
1803: }
1.1 bertrand 1804:
1.81 bertrand 1805: return;
1806: }
1.32 bertrand 1807:
1.1 bertrand 1808:
1.81 bertrand 1809: void
1810: interruption_depassement_pile(int urgence, stackoverflow_context_t scp)
1811: {
1812: if ((urgence == 0) && (routine_recursive != 0))
1.1 bertrand 1813: {
1.81 bertrand 1814: // On peut tenter de récupérer le dépassement de pile. Si la variable
1815: // 'routine_recursive' est non nulle, on récupère l'erreur.
1.1 bertrand 1816:
1.81 bertrand 1817: sigsegv_leave_handler(sortie_interruption_depassement_pile,
1818: (void *) &routine_recursive, NULL, NULL);
1.1 bertrand 1819: }
1820:
1.81 bertrand 1821: // Ici, la panique est totale et il vaut mieux quitter l'application.
1822: interruption3(SIGUSR2);
1823: return;
1824: }
1.1 bertrand 1825:
1826:
1.81 bertrand 1827: int
1828: interruption_violation_access(void *adresse_fautive, int gravite)
1829: {
1830: unsigned char message[] = "+++System : Trying to catch access "
1831: "violation\n";
1.63 bertrand 1832:
1.85 ! bertrand 1833: static int compteur_erreur = 0;
! 1834: int ios;
1.63 bertrand 1835:
1.81 bertrand 1836: if ((gravite == 0) && (routine_recursive != 0))
1837: {
1838: // Il peut s'agir d'un dépassement de pile.
1.63 bertrand 1839:
1.81 bertrand 1840: sigsegv_leave_handler(sortie_interruption_depassement_pile,
1841: (void *) &routine_recursive, NULL, NULL);
1842: }
1.63 bertrand 1843:
1.81 bertrand 1844: // On est dans une bonne vieille violation d'accès. On essaie
1845: // de fermer au mieux l'application.
1.63 bertrand 1846:
1.81 bertrand 1847: compteur_erreur++;
1.63 bertrand 1848:
1.81 bertrand 1849: if (compteur_erreur >= 2)
1850: {
1851: // Erreurs multiples, on arrête l'application.
1852: interruption3(SIGSEGV);
1853: return(0);
1854: }
1.63 bertrand 1855:
1.85 ! bertrand 1856: ios = write(STDERR_FILENO, message, strlen(message));
1.63 bertrand 1857:
1.81 bertrand 1858: if (pid_processus_pere == getpid())
1859: {
1860: longjmp(contexte_initial, -1);
1861: return(1);
1862: }
1863: else
1864: {
1865: longjmp(contexte_processus, -1);
1866: return(1);
1.1 bertrand 1867: }
1868:
1.81 bertrand 1869: // On renvoie 0 parce qu'on décline toute responsabilité quant à la
1870: // suite des événements...
1871: return(0);
1.1 bertrand 1872: }
1.67 bertrand 1873:
1874: // Traitement de rpl_sigstart
1.1 bertrand 1875:
1.67 bertrand 1876: static inline void
1877: signal_start(struct_processus *s_etat_processus, pid_t pid)
1.1 bertrand 1878: {
1.69 bertrand 1879: struct_processus *s_thread_principal;
1880:
1881: verrouillage_gestionnaire_signaux(s_etat_processus);
1882:
1883: if (pid == getpid())
1884: {
1885: (*s_etat_processus).demarrage_fils = d_vrai;
1886: }
1887: else
1888: {
1889: // Envoi d'un signal au thread maître du groupe.
1890:
1891: if ((s_thread_principal = recherche_thread_principal(getpid()))
1892: != NULL)
1893: {
1894: envoi_signal_contexte(s_thread_principal, rpl_sigstart);
1895: }
1896: }
1897:
1898: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67 bertrand 1899: return;
1900: }
1.32 bertrand 1901:
1.67 bertrand 1902: // Traitement de rpl_sigcont
1.1 bertrand 1903:
1.67 bertrand 1904: static inline void
1905: signal_cont(struct_processus *s_etat_processus, pid_t pid)
1906: {
1.69 bertrand 1907: struct_processus *s_thread_principal;
1908:
1909: verrouillage_gestionnaire_signaux(s_etat_processus);
1910:
1911: if (pid == getpid())
1912: {
1913: (*s_etat_processus).redemarrage_processus = d_vrai;
1914: }
1915: else
1916: {
1917: // Envoi d'un signal au thread maître du groupe.
1918:
1919: if ((s_thread_principal = recherche_thread_principal(getpid()))
1920: != NULL)
1921: {
1922: envoi_signal_contexte(s_thread_principal, rpl_sigcont);
1923: }
1924: }
1925:
1926: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1 bertrand 1927: return;
1928: }
1929:
1.67 bertrand 1930: // Traitement de rpl_sigstop
1931:
1932: static inline void
1933: signal_stop(struct_processus *s_etat_processus, pid_t pid)
1.1 bertrand 1934: {
1.67 bertrand 1935: struct_processus *s_thread_principal;
1.1 bertrand 1936:
1.68 bertrand 1937: verrouillage_gestionnaire_signaux(s_etat_processus);
1.32 bertrand 1938:
1.30 bertrand 1939: if (pid == getpid())
1.1 bertrand 1940: {
1941: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1942: == NULL)
1943: {
1.68 bertrand 1944: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1 bertrand 1945: return;
1946: }
1947:
1948: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1949: {
1.69 bertrand 1950: printf("[%d] RPL/SIGSTOP (thread %llu)\n", (int) getpid(),
1.16 bertrand 1951: (unsigned long long) pthread_self());
1952: fflush(stdout);
1.1 bertrand 1953: }
1954:
1955: /*
1956: * var_globale_traitement_retarde_stop :
1957: * 0 -> traitement immédiat
1958: * 1 -> traitement retardé (aucun signal reçu)
1959: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
1960: */
1961:
1.11 bertrand 1962: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
1.1 bertrand 1963: {
1.11 bertrand 1964: (*s_etat_processus).var_volatile_requete_arret = -1;
1.1 bertrand 1965: }
1966: else
1967: {
1.11 bertrand 1968: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
1.1 bertrand 1969: }
1970: }
1971: else
1972: {
1973: // Envoi d'un signal au thread maître du groupe.
1974:
1.67 bertrand 1975: if ((s_thread_principal = recherche_thread_principal(getpid()))
1976: != NULL)
1.1 bertrand 1977: {
1.67 bertrand 1978: envoi_signal_contexte(s_thread_principal, rpl_sigstop);
1.1 bertrand 1979: }
1980: }
1981:
1.68 bertrand 1982: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1 bertrand 1983: return;
1984: }
1985:
1.67 bertrand 1986: // Traitement de rpl_siginject
1987:
1988: static inline void
1989: signal_inject(struct_processus *s_etat_processus, pid_t pid)
1.1 bertrand 1990: {
1.68 bertrand 1991: verrouillage_gestionnaire_signaux(s_etat_processus);
1.32 bertrand 1992:
1.1 bertrand 1993: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1994: {
1.68 bertrand 1995: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1 bertrand 1996: return;
1997: }
1998:
1999: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2000: {
1.67 bertrand 2001: printf("[%d] RPL/SIGINJECT (thread %llu)\n", (int) getpid(),
1.1 bertrand 2002: (unsigned long long) pthread_self());
2003: fflush(stdout);
2004: }
2005:
1.68 bertrand 2006: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1 bertrand 2007: return;
2008: }
2009:
1.67 bertrand 2010: // Récupération des signaux
2011: // - SIGPIPE
2012:
1.1 bertrand 2013: void
1.67 bertrand 2014: interruption5(int signal)
1.1 bertrand 2015: {
1.85 ! bertrand 2016: int ios;
! 2017:
1.67 bertrand 2018: unsigned char message[] = "+++System : SIGPIPE\n"
2019: "+++System : Aborting !\n";
1.1 bertrand 2020:
1.65 bertrand 2021: test_signal(signal);
1.32 bertrand 2022:
1.67 bertrand 2023: if (pid_processus_pere == getpid())
1.1 bertrand 2024: {
1.67 bertrand 2025: envoi_signal_processus(pid_processus_pere, rpl_sigalrm);
1.1 bertrand 2026: }
2027:
1.85 ! bertrand 2028: ios = write(STDERR_FILENO, message, strlen(message));
1.1 bertrand 2029: return;
2030: }
2031:
1.67 bertrand 2032: static inline void
2033: signal_urg(struct_processus *s_etat_processus, pid_t pid)
1.1 bertrand 2034: {
1.67 bertrand 2035: struct_processus *s_thread_principal;
1.30 bertrand 2036:
1.68 bertrand 2037: verrouillage_gestionnaire_signaux(s_etat_processus);
1.32 bertrand 2038:
1.30 bertrand 2039: if (pid == getpid())
1.1 bertrand 2040: {
2041: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2042: == NULL)
2043: {
1.68 bertrand 2044: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1 bertrand 2045: return;
2046: }
2047:
2048: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2049: {
1.67 bertrand 2050: printf("[%d] RPL/SIGURG (thread %llu)\n", (int) getpid(),
1.1 bertrand 2051: (unsigned long long) pthread_self());
2052: fflush(stdout);
2053: }
2054:
2055: (*s_etat_processus).var_volatile_alarme = -1;
2056: (*s_etat_processus).var_volatile_requete_arret = -1;
2057: }
2058: else
2059: {
2060: // Envoi d'un signal au thread maître du groupe.
2061:
1.67 bertrand 2062: if ((s_thread_principal = recherche_thread_principal(getpid()))
2063: != NULL)
1.1 bertrand 2064: {
1.67 bertrand 2065: envoi_signal_contexte(s_thread_principal, rpl_sigurg);
1.1 bertrand 2066: }
2067: }
2068:
1.68 bertrand 2069: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1 bertrand 2070: return;
2071: }
2072:
1.67 bertrand 2073: // Traitement de rpl_sigabort
2074:
2075: static inline void
2076: signal_abort(struct_processus *s_etat_processus, pid_t pid)
1.1 bertrand 2077: {
1.67 bertrand 2078: struct_processus *s_thread_principal;
1.1 bertrand 2079:
1.68 bertrand 2080: verrouillage_gestionnaire_signaux(s_etat_processus);
1.32 bertrand 2081:
1.1 bertrand 2082: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2083: {
1.68 bertrand 2084: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1 bertrand 2085: return;
2086: }
2087:
2088: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2089: {
1.67 bertrand 2090: printf("[%d] RPL/SIGABORT (thread %llu)\n", (int) getpid(),
1.1 bertrand 2091: (unsigned long long) pthread_self());
2092: fflush(stdout);
2093: }
2094:
1.67 bertrand 2095: if (pid == getpid())
1.30 bertrand 2096: {
1.67 bertrand 2097: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2098: == NULL)
2099: {
1.68 bertrand 2100: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67 bertrand 2101: return;
2102: }
1.30 bertrand 2103:
1.67 bertrand 2104: (*s_etat_processus).arret_depuis_abort = -1;
2105:
2106: /*
2107: * var_globale_traitement_retarde_stop :
2108: * 0 -> traitement immédiat
2109: * 1 -> traitement retardé (aucun signal reçu)
2110: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2111: */
2112:
2113: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2114: {
2115: (*s_etat_processus).var_volatile_requete_arret = -1;
2116: }
2117: else
2118: {
2119: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2120: }
2121: }
2122: else
2123: {
2124: (*s_etat_processus).arret_depuis_abort = -1;
2125:
2126: // Envoi d'un signal au thread maître du groupe.
2127:
2128: if ((s_thread_principal = recherche_thread_principal(getpid()))
2129: != NULL)
2130: {
2131: envoi_signal_contexte(s_thread_principal, rpl_sigabort);
2132: }
2133: }
2134:
1.68 bertrand 2135: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67 bertrand 2136: return;
2137: }
2138:
2139: // Récupération des signaux
2140: // - SIGHUP
1.1 bertrand 2141:
2142: void
1.67 bertrand 2143: interruption4(int signal)
2144: {
2145: test_signal(signal);
2146: envoi_signal_processus(getpid(), rpl_sighup);
2147: return;
2148: }
2149:
2150: static inline void
2151: signal_hup(struct_processus *s_etat_processus, pid_t pid)
1.1 bertrand 2152: {
2153: file *fichier;
2154:
2155: unsigned char nom[8 + 64 + 1];
2156:
1.68 bertrand 2157: verrouillage_gestionnaire_signaux(s_etat_processus);
1.32 bertrand 2158:
1.1 bertrand 2159: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2160: {
1.68 bertrand 2161: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1 bertrand 2162: return;
2163: }
2164:
2165: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
2166: (unsigned long) pthread_self());
2167:
2168: if ((fichier = fopen(nom, "w+")) != NULL)
2169: {
2170: fclose(fichier);
2171:
1.85 ! bertrand 2172: stdout = freopen(nom, "w", stdout);
! 2173: stderr = freopen(nom, "w", stderr);
1.1 bertrand 2174: }
2175:
1.85 ! bertrand 2176: stdin = freopen("/dev/null", "r", stdin);
1.1 bertrand 2177:
2178: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2179: {
1.69 bertrand 2180: printf("[%d] RPL/SIGHUP (thread %llu)\n", (int) getpid(),
1.1 bertrand 2181: (unsigned long long) pthread_self());
2182: fflush(stdout);
2183: }
2184:
1.68 bertrand 2185: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1 bertrand 2186: return;
2187: }
2188:
2189: void
1.67 bertrand 2190: traitement_exceptions_gsl(const char *reason, const char *file,
2191: int line, int gsl_errno)
2192: {
1.68 bertrand 2193: code_erreur_gsl = gsl_errno;
2194: envoi_signal_processus(getpid(), rpl_sigexcept);
2195: return;
2196: }
1.67 bertrand 2197:
1.68 bertrand 2198: static inline void
2199: signal_except(struct_processus *s_etat_processus, pid_t pid)
2200: {
2201: verrouillage_gestionnaire_signaux(s_etat_processus);
1.67 bertrand 2202:
2203: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2204: {
1.68 bertrand 2205: deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67 bertrand 2206: return;
2207: }
2208:
1.68 bertrand 2209: (*s_etat_processus).var_volatile_exception_gsl = code_erreur_gsl;
2210: deverrouillage_gestionnaire_signaux(s_etat_processus);
2211:
1.67 bertrand 2212: return;
2213: }
2214:
2215: static inline void
2216: envoi_interruptions(struct_processus *s_etat_processus, enum signaux_rpl signal,
2217: pid_t pid_source)
1.16 bertrand 2218: {
1.67 bertrand 2219: switch(signal)
2220: {
1.69 bertrand 2221: case rpl_signull:
2222: break;
2223:
1.67 bertrand 2224: case rpl_sigint:
2225: signal_int(s_etat_processus, pid_source);
2226: break;
2227:
2228: case rpl_sigterm:
2229: signal_term(s_etat_processus, pid_source);
2230: break;
2231:
2232: case rpl_sigstart:
2233: signal_start(s_etat_processus, pid_source);
2234: break;
2235:
2236: case rpl_sigcont:
2237: signal_cont(s_etat_processus, pid_source);
2238: break;
2239:
2240: case rpl_sigstop:
2241: signal_stop(s_etat_processus, pid_source);
2242: break;
1.30 bertrand 2243:
1.67 bertrand 2244: case rpl_sigabort:
2245: signal_abort(s_etat_processus, pid_source);
2246: break;
2247:
2248: case rpl_sigurg:
2249: signal_urg(s_etat_processus, pid_source);
2250: break;
2251:
2252: case rpl_siginject:
2253: signal_inject(s_etat_processus, pid_source);
2254: break;
2255:
2256: case rpl_sigalrm:
2257: signal_alrm(s_etat_processus, pid_source);
2258: break;
2259:
2260: case rpl_sighup:
2261: signal_hup(s_etat_processus, pid_source);
2262: break;
2263:
2264: case rpl_sigtstp:
2265: signal_tstp(s_etat_processus, pid_source);
2266: break;
2267:
1.68 bertrand 2268: case rpl_sigexcept:
2269: signal_except(s_etat_processus, pid_source);
2270: break;
2271:
1.67 bertrand 2272: default:
1.69 bertrand 2273: if ((*s_etat_processus).langue == 'F')
2274: {
2275: printf("+++System : Spurious signal (%d) !\n", signal);
2276: }
2277: else
2278: {
2279: printf("+++System : Signal inconnu (%d) !\n", signal);
2280: }
2281:
1.67 bertrand 2282: break;
2283: }
1.30 bertrand 2284:
1.67 bertrand 2285: return;
2286: }
1.16 bertrand 2287:
1.67 bertrand 2288: void
2289: scrutation_interruptions(struct_processus *s_etat_processus)
2290: {
2291: // Interruptions qui arrivent sur le processus depuis un
2292: // processus externe.
1.32 bertrand 2293:
1.68 bertrand 2294: // Les pointeurs de lecture pointent sur les prochains éléments
2295: // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à
2296: // écrire.
2297:
1.72 bertrand 2298: # ifndef SEMAPHORES_NOMMES
2299: if (sem_trywait(&((*s_queue_signaux).semaphore)) == 0)
2300: # else
2301: if (sem_trywait(semaphore_queue_signaux) == 0)
2302: # endif
1.68 bertrand 2303: {
2304: if ((*s_queue_signaux).pointeur_lecture !=
2305: (*s_queue_signaux).pointeur_ecriture)
2306: {
2307: // Il y a un signal en attente dans le segment partagé. On le
2308: // traite.
2309:
2310: envoi_interruptions(s_etat_processus,
2311: (*s_queue_signaux).queue[(*s_queue_signaux)
2312: .pointeur_lecture].signal, (*s_queue_signaux).queue
2313: [(*s_queue_signaux).pointeur_lecture].pid);
2314: (*s_queue_signaux).pointeur_lecture =
2315: ((*s_queue_signaux).pointeur_lecture + 1)
2316: % LONGUEUR_QUEUE_SIGNAUX;
2317: }
2318:
1.72 bertrand 2319: # ifndef SEMAPHORES_NOMMES
2320: sem_post(&((*s_queue_signaux).semaphore));
2321: # else
2322: sem_post(semaphore_queue_signaux);
2323: # endif
1.68 bertrand 2324: }
2325:
1.67 bertrand 2326: // Interruptions qui arrivent depuis le groupe courant de threads.
1.29 bertrand 2327:
1.68 bertrand 2328: if (pthread_mutex_trylock(&mutex_interruptions) == 0)
1.16 bertrand 2329: {
1.68 bertrand 2330: if ((*s_etat_processus).pointeur_signal_lecture !=
2331: (*s_etat_processus).pointeur_signal_ecriture)
2332: {
2333: // Il y a un signal dans la queue du thread courant. On le traite.
2334:
2335: envoi_interruptions(s_etat_processus,
2336: (*s_etat_processus).signaux_en_queue
2337: [(*s_etat_processus).pointeur_signal_lecture],
2338: getpid());
2339: (*s_etat_processus).pointeur_signal_lecture =
2340: ((*s_etat_processus).pointeur_signal_lecture + 1)
2341: % LONGUEUR_QUEUE_SIGNAUX;
2342: }
2343:
2344: pthread_mutex_unlock(&mutex_interruptions);
1.67 bertrand 2345: }
2346:
2347: return;
2348: }
2349:
1.69 bertrand 2350: /*
2351: ================================================================================
2352: Fonction renvoyant le nom du segment de mémoire partagée en fonction
2353: du pid du processus.
2354: ================================================================================
2355: Entrée : Chemin absolue servant de racine, pid du processus
2356: --------------------------------------------------------------------------------
2357: Sortie : NULL ou nom du segment
2358: --------------------------------------------------------------------------------
2359: Effet de bord : Néant
2360: ================================================================================
2361: */
2362:
2363: static unsigned char *
2364: nom_segment(unsigned char *chemin, pid_t pid)
2365: {
2366: unsigned char *fichier;
2367:
2368: # ifdef IPCS_SYSV // !POSIX
2369: # ifndef OS2 // !OS2
1.84 bertrand 2370:
1.69 bertrand 2371: if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
2372: sizeof(unsigned char))) == NULL)
2373: {
2374: return(NULL);
2375: }
2376:
2377: sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
2378: # else // OS2
2379: if ((fichier = malloc((10 + 256 + 1) * sizeof(unsigned char)))
2380: == NULL)
2381: {
2382: return(NULL);
2383: }
2384:
2385: sprintf(fichier, "\\SHAREMEM\\RPL-SIGQUEUES-%d", (int) pid);
2386: # endif // OS2
2387: # else // POSIX
2388:
2389: if ((fichier = malloc((1 + 256 + 1) *
2390: sizeof(unsigned char))) == NULL)
2391: {
2392: return(NULL);
2393: }
2394:
2395: sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
2396: # endif
2397:
2398: return(fichier);
2399: }
2400:
2401:
1.71 bertrand 2402: /*
2403: ================================================================================
2404: Fonctions d'envoi d'un signal à un thread ou à un processus.
2405: ================================================================================
2406: Entrée : processus et signal
2407: --------------------------------------------------------------------------------
2408: Sortie : erreur
2409: --------------------------------------------------------------------------------
2410: Effet de bord : Néant
2411: ================================================================================
2412: */
2413:
1.67 bertrand 2414: int
2415: envoi_signal_processus(pid_t pid, enum signaux_rpl signal)
2416: {
1.83 bertrand 2417: # ifndef OS2
2418: int segment;
2419: # endif
1.69 bertrand 2420:
1.75 bertrand 2421: # ifndef IPCS_SYSV
2422: # ifdef SEMAPHORES_NOMMES
2423: sem_t *semaphore;
2424: # endif
2425: # else
1.83 bertrand 2426: # ifndef OS2
2427: int desc;
2428: key_t clef;
2429: # endif
1.75 bertrand 2430: # endif
1.72 bertrand 2431:
1.69 bertrand 2432: struct_queue_signaux *queue;
2433:
2434: unsigned char *nom;
2435:
1.67 bertrand 2436: // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en
2437: // mémoire puis d'y inscrire le signal à traiter.
2438:
1.69 bertrand 2439: if (pid == getpid())
2440: {
2441: // Le signal est envoyé au même processus.
2442:
2443: if (s_queue_signaux == NULL)
2444: {
2445: return(1);
2446: }
2447:
1.72 bertrand 2448: # ifndef SEMAPHORES_NOMMES
1.78 bertrand 2449: while(sem_wait(&((*s_queue_signaux).semaphore)) != 0)
1.72 bertrand 2450: # else
1.78 bertrand 2451: while(sem_wait(semaphore_queue_signaux) != 0)
1.72 bertrand 2452: # endif
1.69 bertrand 2453: {
1.78 bertrand 2454: if (errno != EINTR)
2455: {
2456: return(1);
2457: }
1.69 bertrand 2458: }
2459:
2460: (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
2461: .pid = pid;
2462: (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
2463: .signal = signal;
2464:
2465: (*s_queue_signaux).pointeur_ecriture =
2466: ((*s_queue_signaux).pointeur_ecriture + 1)
2467: % LONGUEUR_QUEUE_SIGNAUX;
2468:
1.72 bertrand 2469: # ifndef SEMAPHORES_NOMMES
2470: if (sem_post(&((*s_queue_signaux).semaphore)) != 0)
2471: # else
2472: if (sem_post(semaphore_queue_signaux) != 0)
2473: # endif
1.69 bertrand 2474: {
2475: return(1);
2476: }
2477: }
2478: else
2479: {
2480: // Le signal est envoyé depuis un processus distinct.
2481:
1.75 bertrand 2482: # ifdef IPCS_SYSV
1.76 bertrand 2483: if ((nom = nom_segment(racine_segment, pid)) == NULL)
1.75 bertrand 2484: {
2485: return(1);
2486: }
2487:
1.83 bertrand 2488: # ifndef OS2 // SysV
2489: if ((desc = open(nom, O_RDWR)) == -1)
2490: {
2491: free(nom);
2492: return(1);
2493: }
2494:
2495: close(desc);
1.75 bertrand 2496:
1.83 bertrand 2497: if ((clef = ftok(nom, 1)) == -1)
2498: {
2499: free(nom);
2500: return(1);
2501: }
1.75 bertrand 2502:
2503: free(nom);
1.69 bertrand 2504:
1.83 bertrand 2505: if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0))
2506: == -1)
2507: {
2508: return(1);
2509: }
1.69 bertrand 2510:
1.83 bertrand 2511: queue = shmat(segment, NULL, 0);
2512: # else // OS/2
2513: if (DosGetNamedSharedMem((PVOID) &queue, nom,
2514: PAG_WRITE | PAG_READ) != 0)
2515: {
2516: free(nom);
2517: return(1);
2518: }
1.69 bertrand 2519:
1.83 bertrand 2520: free(nom);
2521: # endif
1.75 bertrand 2522: # else // POSIX
2523: if ((nom = nom_segment(racine_segment, pid)) == NULL)
2524: {
2525: return(1);
2526: }
1.69 bertrand 2527:
1.75 bertrand 2528: if ((segment = shm_open(nom, O_RDWR, 0)) == -1)
1.72 bertrand 2529: {
1.75 bertrand 2530: free(nom);
1.72 bertrand 2531: return(1);
2532: }
1.75 bertrand 2533:
2534: free(nom);
2535:
2536: if ((queue = mmap(NULL, sizeof(struct_queue_signaux),
2537: PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0)) ==
2538: MAP_FAILED)
1.72 bertrand 2539: {
1.75 bertrand 2540: close(segment);
1.72 bertrand 2541: return(1);
2542: }
1.75 bertrand 2543: # endif
1.72 bertrand 2544:
1.75 bertrand 2545: // À ce moment, le segment de mémoire partagée est projeté
2546: // dans l'espace du processus.
2547:
2548: # ifndef IPCS_SYSV // POSIX
2549: # ifndef SEMAPHORES_NOMMES
1.78 bertrand 2550: while(sem_wait(&((*queue).semaphore)) != 0)
1.75 bertrand 2551: {
1.78 bertrand 2552: if (errno != EINTR)
2553: {
2554: return(1);
2555: }
1.75 bertrand 2556: }
2557: # else
1.80 bertrand 2558: if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED)
1.75 bertrand 2559: {
2560: return(1);
2561: }
2562:
1.78 bertrand 2563: while(sem_wait(semaphore) != 0)
1.75 bertrand 2564: {
1.78 bertrand 2565: if (errno != EINTR)
2566: {
2567: sem_close(semaphore);
2568: return(1);
2569: }
1.75 bertrand 2570: }
2571: # endif
2572: # else // IPCS_SYSV
1.78 bertrand 2573: while(sem_wait(&((*queue).semaphore)) != 0)
1.72 bertrand 2574: {
1.78 bertrand 2575: if (errno != EINTR)
2576: {
2577: return(1);
2578: }
1.72 bertrand 2579: }
2580: # endif
1.69 bertrand 2581:
2582: (*queue).queue[(*queue).pointeur_ecriture].pid = getpid();
2583: (*queue).queue[(*queue).pointeur_ecriture].signal = signal;
2584:
2585: (*queue).pointeur_ecriture = ((*queue).pointeur_ecriture + 1)
2586: % LONGUEUR_QUEUE_SIGNAUX;
2587:
1.75 bertrand 2588: # ifndef IPCS_SYSV // POSIX
2589: # ifndef SEMAPHORES_NOMMES
2590: if (sem_post(&((*queue).semaphore)) != 0)
2591: {
2592: return(1);
2593: }
2594: # else
2595: if (sem_post(semaphore) != 0)
2596: {
2597: sem_close(semaphore);
2598: return(1);
2599: }
2600:
2601: if (sem_close(semaphore) != 0)
2602: {
2603: return(1);
2604: }
2605: # endif
2606:
2607: if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
1.72 bertrand 2608: {
1.75 bertrand 2609: close(segment);
1.72 bertrand 2610: return(1);
2611: }
1.75 bertrand 2612: # else // IPCS_SYSV
2613: if (sem_post(&((*queue).semaphore)) != 0)
1.72 bertrand 2614: {
2615: return(1);
2616: }
2617:
1.83 bertrand 2618: # ifndef OS2 // SysV
2619: if (shmdt(queue) != 0)
2620: {
2621: return(1);
2622: }
2623: # else // OS/2
2624: // Pendant de DosGetNamedSHaredMem()
2625: # endif
1.72 bertrand 2626: # endif
1.69 bertrand 2627: }
2628:
1.67 bertrand 2629: return(0);
2630: }
2631:
2632: int
2633: envoi_signal_thread(pthread_t tid, enum signaux_rpl signal)
2634: {
2635: // Un signal est envoyé d'un thread à un autre thread du même processus.
2636:
1.68 bertrand 2637: volatile struct_liste_chainee_volatile *l_element_courant;
2638:
2639: struct_processus *s_etat_processus;
2640:
2641: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
2642: {
2643: return(1);
2644: }
2645:
2646: l_element_courant = liste_threads;
2647:
2648: while(l_element_courant != NULL)
2649: {
2650: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
2651: == getpid()) && (pthread_equal((*((struct_thread *)
2652: (*l_element_courant).donnee)).tid, tid) != 0))
2653: {
2654: break;
2655: }
2656:
2657: l_element_courant = (*l_element_courant).suivant;
2658: }
2659:
2660: if (l_element_courant == NULL)
2661: {
2662: pthread_mutex_unlock(&mutex_liste_threads);
2663: return(1);
2664: }
2665:
2666: if (pthread_mutex_lock(&mutex_interruptions) != 0)
2667: {
2668: pthread_mutex_unlock(&mutex_liste_threads);
2669: return(1);
2670: }
2671:
2672: s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))
2673: .s_etat_processus;
2674:
2675: (*s_etat_processus).signaux_en_queue
2676: [(*s_etat_processus).pointeur_signal_ecriture] = signal;
2677: (*s_etat_processus).pointeur_signal_ecriture =
2678: ((*s_etat_processus).pointeur_signal_ecriture + 1)
2679: % LONGUEUR_QUEUE_SIGNAUX;
2680:
2681: if (pthread_mutex_unlock(&mutex_interruptions) != 0)
2682: {
2683: pthread_mutex_unlock(&mutex_liste_threads);
2684: return(1);
2685: }
2686:
2687: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
2688: {
2689: return(1);
2690: }
2691:
1.67 bertrand 2692: return(0);
2693: }
2694:
2695: int
2696: envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
2697: enum signaux_rpl signal)
2698: {
1.68 bertrand 2699: pthread_mutex_lock(&mutex_interruptions);
1.67 bertrand 2700: (*s_etat_processus_a_signaler).signaux_en_queue
1.68 bertrand 2701: [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =
1.67 bertrand 2702: signal;
1.68 bertrand 2703: (*s_etat_processus_a_signaler).pointeur_signal_ecriture =
2704: ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)
2705: % LONGUEUR_QUEUE_SIGNAUX;
2706: pthread_mutex_unlock(&mutex_interruptions);
1.67 bertrand 2707:
2708: return(0);
2709: }
2710:
2711:
2712: /*
2713: ================================================================================
2714: Fonction créant un segment de mémoire partagée destiné à contenir
2715: la queue des signaux.
2716: ================================================================================
2717: Entrée : structure de description du processus
2718: --------------------------------------------------------------------------------
2719: Sortie : Néant
2720: --------------------------------------------------------------------------------
2721: Effet de bord : Néant
2722: ================================================================================
2723: */
2724:
2725: void
2726: creation_queue_signaux(struct_processus *s_etat_processus)
2727: {
2728: unsigned char *nom;
2729:
1.69 bertrand 2730: racine_segment = (*s_etat_processus).chemin_fichiers_temporaires;
2731:
1.67 bertrand 2732: # ifndef IPCS_SYSV // POSIX
1.71 bertrand 2733: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
2734: getpid())) == NULL)
2735: {
2736: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2737: return;
2738: }
1.16 bertrand 2739:
1.71 bertrand 2740: if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
2741: S_IRUSR | S_IWUSR)) == -1)
2742: {
2743: free(nom);
2744: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2745: return;
2746: }
1.16 bertrand 2747:
1.71 bertrand 2748: if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1)
2749: {
2750: free(nom);
2751: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2752: return;
2753: }
1.16 bertrand 2754:
1.71 bertrand 2755: s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux),
2756: PROT_READ | PROT_WRITE, MAP_SHARED, f_queue_signaux, 0);
1.67 bertrand 2757:
1.71 bertrand 2758: if (((void *) s_queue_signaux) == ((void *) -1))
2759: {
2760: if (shm_unlink(nom) == -1)
2761: {
2762: free(nom);
2763: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2764: return;
2765: }
1.67 bertrand 2766:
2767: free(nom);
2768: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1.16 bertrand 2769: return;
2770: }
2771:
1.67 bertrand 2772: free(nom);
1.75 bertrand 2773:
1.71 bertrand 2774: # ifndef SEMAPHORES_NOMMES
2775: sem_init(&((*s_queue_signaux).semaphore), 1, 1);
2776: # else
1.80 bertrand 2777: if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
1.72 bertrand 2778: == SEM_FAILED)
1.71 bertrand 2779: {
2780: (*s_etat_processus).erreur_systeme = d_es_processus;
2781: return;
2782: }
2783: # endif
1.67 bertrand 2784:
1.71 bertrand 2785: (*s_queue_signaux).pointeur_lecture = 0;
2786: (*s_queue_signaux).pointeur_ecriture = 0;
1.67 bertrand 2787:
1.71 bertrand 2788: if (msync(s_queue_signaux, sizeof(struct_queue_signaux), 0))
1.16 bertrand 2789: {
1.71 bertrand 2790: (*s_etat_processus).erreur_systeme = d_es_processus;
1.16 bertrand 2791: return;
2792: }
1.75 bertrand 2793: # else // IPCS_SYSV
1.71 bertrand 2794: # ifndef OS2
1.75 bertrand 2795: int segment;
2796: int support;
1.71 bertrand 2797:
2798: key_t clef;
1.67 bertrand 2799:
1.71 bertrand 2800: // Création d'un segment de données associé au PID du processus
2801: // courant
1.16 bertrand 2802:
1.71 bertrand 2803: if ((nom = nom_segment((*s_etat_processus)
2804: .chemin_fichiers_temporaires, getpid())) == NULL)
2805: {
2806: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2807: return;
2808: }
2809:
1.76 bertrand 2810: if ((support = open(nom, O_RDWR | O_CREAT | O_EXCL,
1.75 bertrand 2811: S_IRUSR | S_IWUSR)) == -1)
1.71 bertrand 2812: {
2813: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
2814: return;
2815: }
2816:
2817: if ((clef = ftok(nom, 1)) == -1)
2818: {
2819: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2820: return;
2821: }
1.1 bertrand 2822:
1.75 bertrand 2823: close(support);
1.71 bertrand 2824: free(nom);
1.1 bertrand 2825:
1.75 bertrand 2826: if ((segment = shmget(clef, sizeof(struct_queue_signaux),
1.71 bertrand 2827: IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
2828: {
2829: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2830: return;
2831: }
2832:
1.75 bertrand 2833: s_queue_signaux = shmat(segment, NULL, 0);
2834: f_queue_signaux = segment;
1.71 bertrand 2835:
1.75 bertrand 2836: if (((void *) s_queue_signaux) == ((void *) -1))
1.71 bertrand 2837: {
1.75 bertrand 2838: if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
1.71 bertrand 2839: {
2840: (*s_etat_processus).erreur_systeme =
2841: d_es_allocation_memoire;
2842: return;
2843: }
2844:
2845: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2846: return;
2847: }
1.75 bertrand 2848:
2849: sem_init(&((*s_queue_signaux).semaphore), 1, 1);
2850: (*s_queue_signaux).pointeur_lecture = 0;
2851: (*s_queue_signaux).pointeur_ecriture = 0;
1.71 bertrand 2852: # else // OS/2
2853: if ((nom = nom_segment(NULL, getpid())) == NULL)
2854: {
2855: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2856: return;
2857: }
2858:
1.83 bertrand 2859: if (DosAllocSharedMem((PVOID) &s_queue_signaux, nom,
2860: sizeof(struct_queue_signaux),
1.71 bertrand 2861: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
2862: {
2863: free(nom);
2864: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2865: return;
2866: }
1.67 bertrand 2867:
1.71 bertrand 2868: free(nom);
1.83 bertrand 2869:
2870: sem_init(&((*s_queue_signaux).semaphore), 1, 1);
2871: (*s_queue_signaux).pointeur_lecture = 0;
2872: (*s_queue_signaux).pointeur_ecriture = 0;
1.71 bertrand 2873: # endif
1.67 bertrand 2874: # endif
2875:
1.1 bertrand 2876: return;
2877: }
2878:
1.67 bertrand 2879:
2880: /*
2881: ================================================================================
2882: Fonction libérant le segment de mémoire partagée destiné à contenir
2883: la queue des signaux.
2884: ================================================================================
2885: Entrée : structure de description du processus
2886: --------------------------------------------------------------------------------
2887: Sortie : Néant
2888: --------------------------------------------------------------------------------
2889: Effet de bord : Néant
2890: ================================================================================
2891: */
2892:
2893: void
2894: liberation_queue_signaux(struct_processus *s_etat_processus)
1.66 bertrand 2895: {
1.67 bertrand 2896: # ifdef IPCS_SYSV // SystemV
2897: # ifndef OS2
1.75 bertrand 2898: if (shmdt(s_queue_signaux) == -1)
2899: {
2900: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2901: return;
2902: }
1.67 bertrand 2903: # else // OS/2
2904: # endif
2905: # else // POSIX
1.72 bertrand 2906: # ifndef SEMAPHORES_NOMMES
2907: sem_close(&((*s_queue_signaux).semaphore));
2908: # else
2909: sem_close(semaphore_queue_signaux);
2910: # endif
1.70 bertrand 2911:
1.67 bertrand 2912: if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
1.66 bertrand 2913: {
1.67 bertrand 2914: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2915: return;
1.66 bertrand 2916: }
1.69 bertrand 2917:
2918: close(f_queue_signaux);
1.67 bertrand 2919: # endif
1.66 bertrand 2920:
2921: return;
2922: }
2923:
1.67 bertrand 2924:
2925: /*
2926: ================================================================================
2927: Fonction détruisant le segment de mémoire partagée destiné à contenir
2928: la queue des signaux.
2929: ================================================================================
2930: Entrée : structure de description du processus
2931: --------------------------------------------------------------------------------
2932: Sortie : Néant
2933: --------------------------------------------------------------------------------
2934: Effet de bord : Néant
2935: ================================================================================
2936: */
2937:
1.66 bertrand 2938: void
1.67 bertrand 2939: destruction_queue_signaux(struct_processus *s_etat_processus)
1.66 bertrand 2940: {
1.83 bertrand 2941: # ifndef OS2
2942: unsigned char *nom;
2943: # endif
1.66 bertrand 2944:
1.67 bertrand 2945: # ifdef IPCS_SYSV // SystemV
1.71 bertrand 2946: # ifndef OS2
1.75 bertrand 2947: // Il faut commencer par éliminer le sémaphore.
2948:
2949: if (semctl((*s_queue_signaux).semaphore.sem, 0, IPC_RMID) == -1)
2950: {
2951: (*s_etat_processus).erreur_systeme = d_es_processus;
2952: return;
2953: }
2954:
2955: unlink((*s_queue_signaux).semaphore.path);
2956:
2957: if (shmdt(s_queue_signaux) == -1)
1.71 bertrand 2958: {
2959: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2960: return;
2961: }
2962:
1.75 bertrand 2963: if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
1.71 bertrand 2964: {
2965: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2966: return;
2967: }
2968:
2969: if ((nom = nom_segment((*s_etat_processus)
2970: .chemin_fichiers_temporaires, getpid())) == NULL)
2971: {
2972: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2973: return;
2974: }
1.66 bertrand 2975:
1.71 bertrand 2976: unlink(nom);
2977: free(nom);
2978: # else
1.83 bertrand 2979: sem_close(&((*s_queue_signaux).semaphore));
2980: sem_destroy(&((*s_queue_signaux).semaphore));
2981:
2982: if (DosFreeMem(s_queue_signaux) != 0)
1.71 bertrand 2983: {
2984: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2985: return;
2986: }
2987: # endif
1.67 bertrand 2988: # else // POSIX
1.72 bertrand 2989: # ifndef SEMAPHORES_NOMMES
2990: sem_close(&((*s_queue_signaux).semaphore));
2991: sem_destroy(&((*s_queue_signaux).semaphore));
2992: # else
2993: sem_close(semaphore_queue_signaux);
1.80 bertrand 2994: sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);
1.72 bertrand 2995: # endif
1.67 bertrand 2996:
1.70 bertrand 2997: if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
2998: {
2999: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3000: return;
3001: }
3002:
3003: if ((nom = nom_segment(NULL, getpid())) == NULL)
3004: {
3005: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3006: return;
3007: }
1.66 bertrand 3008:
1.70 bertrand 3009: close(f_queue_signaux);
1.66 bertrand 3010:
1.70 bertrand 3011: if (shm_unlink(nom) != 0)
3012: {
3013: free(nom);
3014: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3015: return;
3016: }
1.69 bertrand 3017:
1.67 bertrand 3018: free(nom);
3019: # endif
3020:
1.66 bertrand 3021: return;
3022: }
3023:
1.1 bertrand 3024: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>