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