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