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