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