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