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