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