![]() ![]() | ![]() |
1.1 bertrand 1: /*
2: ================================================================================
1.8.2.2 ! bertrand 3: RPL/2 (R) version 4.0.23
1.7 bertrand 4: Copyright (C) 1989-2011 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:
23: #define __BROKEN_SIGINFO_ROUTINES__
24: #include "rpl-conv.h"
25:
26: #ifdef _BROKEN_SIGINFO
27:
28: #define longueur_queue 256
29: #define nombre_queues 13
30:
31: static int *fifos;
32: static int markov;
33: static sem_t *semaphores[nombre_queues];
34: static sem_t *semaphore_global;
35:
36: #ifdef IPCS_SYSV
1.5 bertrand 37: #ifndef OS2
1.1 bertrand 38: static unsigned char *chemin = NULL;
39: #endif
1.5 bertrand 40: #endif
41:
42: #ifdef OS2
43: PVOID ptr_os2;
44: #else
45: static int segment;
46: #endif
1.1 bertrand 47:
48: static unsigned char *
49: nom_segment(unsigned char *chemin, pid_t pid)
50: {
51: unsigned char *fichier;
52:
53: # ifdef IPCS_SYSV
1.5 bertrand 54:
55: # ifndef OS2
56:
1.1 bertrand 57: if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
58: sizeof(unsigned char))) == NULL)
59: {
60: return(NULL);
61: }
62:
63: sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
1.5 bertrand 64:
65: # else
66:
67: if ((fichier = malloc((10 + 256 + 1) * sizeof(unsigned char))) == NULL)
68: {
69: return(NULL);
70: }
71:
72: sprintf(fichier, "\\SHAREMEM\\RPL-SIGQUEUES-%d", (int) pid);
73:
74: # endif
1.1 bertrand 75: # else
1.5 bertrand 76:
1.1 bertrand 77: if ((fichier = malloc((1 + 256 + 1) *
78: sizeof(unsigned char))) == NULL)
79: {
80: return(NULL);
81: }
82:
83: sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
1.5 bertrand 84:
1.1 bertrand 85: # endif
86:
87: return(fichier);
88: }
89:
90: static unsigned char *
91: nom_semaphore(pid_t pid, int queue)
92: {
93: unsigned char *fichier;
94:
95: if ((fichier = malloc((256 + 1) * sizeof(unsigned char))) == NULL)
96: {
97: return(NULL);
98: }
99:
1.5 bertrand 100: sprintf(fichier, "/RPL-SIGSEMAPHORES-%d-%d", (int) pid, queue);
1.1 bertrand 101:
102: return(fichier);
103: }
104:
105: static inline int
106: queue_de_signal(int signal)
107: {
108: switch(signal)
109: {
110: case SIGINT:
111: return(0);
112: case SIGTSTP:
113: return(1);
114: case SIGCONT:
115: return(2);
116: case SIGURG:
117: return(3);
118: case SIGPIPE:
119: return(4);
120: case SIGALRM:
121: return(5);
122: case SIGFSTOP:
123: return(6);
124: case SIGSTART:
125: return(7);
126: case SIGINJECT:
127: return(8);
128: case SIGABORT:
129: return(9);
130: case SIGFABORT:
131: return(10);
132: case SIGSEGV:
133: return(11);
134: case SIGBUS:
135: return(12);
136: }
137:
138: return(-1);
139: }
140:
141: void
142: creation_fifos_signaux(struct_processus *s_etat_processus)
143: {
144: /*
145: * Signaux utilisés
146: * SIGINT, SIGTSTP, SIGCONT, SIGURG, SIGPIPE, SIGALRM, SIGFSTOP,
147: * SIGSTART, SIGINJECT, SIGABORT, SIGFABORT
148: */
149:
150: int i;
151:
152: unsigned char *nom;
153:
154: # ifndef IPCS_SYSV // POSIX
155:
156: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
157: getpid())) == NULL)
158: {
159: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
160: return;
161: }
162:
163: if ((segment = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
164: S_IRUSR | S_IWUSR)) == -1)
165: {
166: free(nom);
167: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
168: return;
169: }
170:
171: if (ftruncate(segment, nombre_queues * ((2 * longueur_queue) + 4) *
172: sizeof(int)) == -1)
173: {
174: free(nom);
175: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
176: return;
177: }
178:
179: fifos = mmap(NULL, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
180: PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0);
181: close(segment);
182:
183: if (((void *) fifos) == ((void *) -1))
184: {
185: if (shm_unlink(nom) == -1)
186: {
187: free(nom);
188: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
189: return;
190: }
191:
192: free(nom);
193: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
194: return;
195: }
196:
197: free(nom);
198:
199: # else // SystemV
1.5 bertrand 200: # ifndef OS2
1.1 bertrand 201:
202: file *desc;
203:
204: key_t clef;
205:
206: // Création d'un segment de données associé au PID du processus courant
207:
208: chemin = (*s_etat_processus).chemin_fichiers_temporaires;
209:
210: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
211: getpid())) == NULL)
212: {
213: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
214: return;
215: }
216:
217: if ((desc = fopen(nom, "w")) == NULL)
218: {
219: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
220: return;
221: }
222:
223: fclose(desc);
224:
225: if ((clef = ftok(nom, 1)) == -1)
226: {
227: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
228: return;
229: }
230:
231: free(nom);
232:
233: if ((segment = shmget(clef,
234: nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
235: IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
236: {
237: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
238: return;
239: }
240:
241: fifos = shmat(segment, NULL, 0);
242:
243: if (((void *) fifos) == ((void *) -1))
244: {
245: if (shmctl(segment, IPC_RMID, 0) == -1)
246: {
247: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
248: return;
249: }
250:
251: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
252: return;
253: }
254:
1.5 bertrand 255: # else
256:
257: if ((nom = nom_segment(NULL, getpid())) == NULL)
258: {
259: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
260: return;
261: }
262:
263: if (DosAllocSharedMem(&ptr_os2, nom, nombre_queues *
264: ((2 * longueur_queue) + 4) * sizeof(int),
265: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
266: {
267: free(nom);
268: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
269: return;
270: }
271:
272: free(nom);
273: fifos = ptr_os2;
274:
275: # endif
1.1 bertrand 276: # endif
277:
278: /*
279: * Structure d'une queue
280: * 0 : pointeur en lecture sur le premier emplacement libre (int)
281: * 1 : pointeur en écriture sur le premier emplacement à lire (int)
282: * 2 : longueur de la queue (int)
283: * 3 : éléments restants (int)
284: * 4 à 4 + (2) : queue (int)
285: * 4 + (2) + 1 ) 4 + 2 * (2) : horodatage en centième de secondes.
286: */
287:
288: for(i = 0; i < nombre_queues; i++)
289: {
290: fifos[(i * (longueur_queue + 4))] = 0;
291: fifos[(i * (longueur_queue + 4)) + 1] = 0;
292: fifos[(i * (longueur_queue + 4)) + 2] = longueur_queue;
293: fifos[(i * (longueur_queue + 4)) + 3] = longueur_queue;
294: }
295:
296: // Création des sémaphores : un sémaphore par signal et par queue
297: // plus un sémaphore global pour tous les threads.
298:
299: for(i = 0; i < nombre_queues; i++)
300: {
301: if ((nom = nom_semaphore(getpid(), i)) == NULL)
302: {
303: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
304: return;
305: }
306:
307: // Le sémaphore est créé en écrasant si nécessaire un sémaphore
308: // préexistant. Comme le nom du sémaphore contient l'identifiant du
309: // processus, il est anormal d'avoir un sémaphore de même nom
310: // préexistant.
311:
312: if ((semaphores[i] = sem_open(nom, O_CREAT, S_IRUSR | S_IWUSR,
313: 1)) == SEM_FAILED)
314: {
315: (*s_etat_processus).erreur_systeme = d_es_semaphore;
316: return;
317: }
318:
319: free(nom);
320: }
321:
322:
323: if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
324: {
325: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
326: return;
327: }
328:
329: if ((semaphore_global = sem_open(nom, O_CREAT, S_IRUSR | S_IWUSR,
330: 1)) == SEM_FAILED)
331: {
332: (*s_etat_processus).erreur_systeme = d_es_semaphore;
333: return;
334: }
335:
336: free(nom);
337:
338: markov = 0;
339:
340: return;
341: }
342:
343: void
344: liberation_fifos_signaux(struct_processus *s_etat_processus)
345: {
346: int i;
347:
348: # ifdef IPCS_SYSV // SystemV
1.5 bertrand 349: # ifndef OS2
1.1 bertrand 350:
351: if (shmdt(fifos) == -1)
352: {
353: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
354: return;
355: }
356:
1.5 bertrand 357: # else
358:
359: if (DosFreeMem(fifos) != 0)
360: {
361: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
362: return;
363: }
364:
365: # endif
1.1 bertrand 366: # else // POSIX
367:
368: if (munmap(fifos, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int))
369: != 0)
370: {
371: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
372: return;
373: }
374:
375: # endif
376:
377: for(i = 0; i < nombre_queues; i++)
378: {
379: if (sem_close(semaphores[i]) != 0)
380: {
381: (*s_etat_processus).erreur_systeme = d_es_semaphore;
382: return;
383: }
384: }
385:
386: if (sem_close(semaphore_global) != 0)
387: {
388: (*s_etat_processus).erreur_systeme = d_es_semaphore;
389: return;
390: }
391:
392: return;
393: }
394:
395: void
396: destruction_fifos_signaux(struct_processus *s_etat_processus)
397: {
398: int i;
399:
400: unsigned char *nom;
401:
402: # ifdef IPCS_SYSV // SystemV
1.5 bertrand 403: # ifndef OS2
1.1 bertrand 404:
405: if (shmdt(fifos) == -1)
406: {
407: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
408: return;
409: }
410:
411: if (shmctl(segment, IPC_RMID, 0) == -1)
412: {
413: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
414: return;
415: }
416:
417: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
418: getpid())) == NULL)
419: {
420: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
421: return;
422: }
423:
424: unlink(nom);
425: free(nom);
426:
1.5 bertrand 427: # else
428:
429: if (DosFreeMem(fifos) != 0)
430: {
431: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
432: return;
433: }
434:
435: # endif
1.1 bertrand 436: # else // POSIX
437:
438: if (munmap(fifos, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int))
439: != 0)
440: {
441: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
442: return;
443: }
444:
445: if ((nom = nom_segment(NULL, getpid())) == NULL)
446: {
447: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
448: return;
449: }
450:
451: if (shm_unlink(nom) != 0)
452: {
453: free(nom);
454: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
455: return;
456: }
457:
458: free(nom);
459:
460: # endif
461:
462: for(i = 0; i < nombre_queues; i++)
463: {
464: if ((nom = nom_semaphore(getpid(), i)) == NULL)
465: {
466: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
467: return;
468: }
469:
470: if (sem_unlink(nom) != 0)
471: {
472: (*s_etat_processus).erreur_systeme = d_es_semaphore;
473: return;
474: }
475:
476: free(nom);
477: }
478:
479: if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
480: {
481: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
482: return;
483: }
484:
485: if (sem_unlink(nom) != 0)
486: {
487: (*s_etat_processus).erreur_systeme = d_es_semaphore;
488: return;
489: }
490:
491: free(nom);
492:
493: return;
494: }
495:
496: static inline int
497: horodatage()
498: {
499: int ts;
500:
501: struct timeval tv;
502:
503: gettimeofday(&tv, NULL);
504: ts = (int) ((tv.tv_sec * 100) + (tv.tv_usec / 10000));
505:
506: return(ts);
507: }
508:
1.2 bertrand 509: int
1.1 bertrand 510: queue_in(pid_t pid, int signal)
511: {
512: int queue;
513: int *base;
514: int *buffer;
515: int horodatage_initial;
1.5 bertrand 516: # ifndef OS2
1.1 bertrand 517: int identifiant;
1.5 bertrand 518: # endif
1.1 bertrand 519: int *projection_fifos;
520:
521: sem_t *semaphore;
522:
523: queue = queue_de_signal(signal);
524:
525: unsigned char *nom;
526:
527: # ifndef IPCS_SYSV
528:
529: // Ouverture des projections
530:
531: if ((nom = nom_segment(NULL, pid)) == NULL)
532: {
533: return(-1);
534: }
535:
536: // Dans le cas de SIGSTART, premier signal envoyé à un processus fils,
537: // il convient d'attendre que le fichier support soit effectivement
538: // accessible. Dans tous les autres cas, ce fichier doit exister. S'il
539: // n'existe plus, le processus associé n'existe plus.
540:
541: if (signal == SIGSTART)
542: {
543: horodatage_initial = horodatage();
544:
545: while((identifiant = shm_open(nom, O_RDWR, S_IRUSR | S_IWUSR)) == -1)
546: {
547: if (abs(horodatage_initial - horodatage()) > 500)
548: {
549: return(-1);
550: }
551: }
552: }
553: else
554: {
555: if ((identifiant = shm_open(nom, O_RDWR, S_IRUSR | S_IWUSR)) == -1)
556: {
557: return(-1);
558: }
559: }
560:
561: projection_fifos = mmap(NULL, nombre_queues * ((2 * longueur_queue) + 4)
562: * sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, identifiant, 0);
563: close(identifiant);
564:
565: if (((void *) projection_fifos) == ((void *) -1))
566: {
567: return(-1);
568: }
569:
570: # else // Traitement à l'aide d'IPCS SystemV
571:
1.5 bertrand 572: # ifndef OS2
1.1 bertrand 573: key_t clef;
574:
575: struct stat s_stat;
1.5 bertrand 576: # endif
577:
578: // Dans le cas de SIGSTART, premier signal envoyé à un processus fils,
579: // il convient d'attendre que le fichier support soit effectivement
580: // accessible. Dans tous les autres cas, ce fichier doit exister. S'il
581: // n'existe plus, le processus associé n'existe plus.
582:
583: # ifndef OS2
1.1 bertrand 584:
585: // Ouverture des projections
586:
587: if ((nom = nom_segment(chemin, pid)) == NULL)
588: {
589: return(-1);
590: }
591:
592: if (signal == SIGSTART)
593: {
594: // On attend que le fichier sois présent
595:
596: horodatage_initial = horodatage();
597:
598: while(stat(nom, &s_stat) != 0)
599: {
600: if (abs(horodatage_initial - horodatage()) > 500)
601: {
602: return(-1);
603: }
604: }
605: }
606:
607: if ((clef = ftok(nom, 1)) == -1)
608: {
609: return(-1);
610: }
611:
612: free(nom);
613:
614: if (signal == SIGSTART)
615: {
616: while((identifiant = shmget(clef,
617: nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
618: S_IRUSR | S_IWUSR)) == -1);
619: }
620: else
621: {
622: if ((identifiant = shmget(clef,
623: nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
624: S_IRUSR | S_IWUSR)) == -1)
625: {
626: return(-1);
627: }
628: }
629:
630: projection_fifos = shmat(identifiant, NULL, 0);
631:
632: if (((void *) projection_fifos) == ((void *) -1))
633: {
634: return(-1);
635: }
636:
1.5 bertrand 637: # else
638:
639: // Ouverture des projections
640:
641: if ((nom = nom_segment(NULL, pid)) == NULL)
642: {
643: return(-1);
644: }
645:
646: if (signal == SIGSTART)
647: {
648: horodatage_initial = horodatage();
649:
650: while(DosGetNamedSharedMem(&ptr_os2, nom,
651: PAG_READ | PAG_WRITE | PAG_COMMIT) != 0)
652: {
653: if (abs(horodatage_initial - horodatage()) > 500)
654: {
655: return(-1);
656: }
657: }
658: }
659: else
660: {
661: if (DosGetNamedSharedMem(&ptr_os2, nom,
662: PAG_READ | PAG_WRITE) != 0)
663: {
664: return(-1);
665: }
666: }
667:
668: projection_fifos = ptr_os2;
669:
670: # endif
1.1 bertrand 671: # endif
672:
673: if ((nom = nom_semaphore(pid, queue)) == NULL)
674: {
675: # ifdef IPCS_SYSV
1.5 bertrand 676: # ifndef OS2
1.1 bertrand 677: shmdt(projection_fifos);
678: # else
1.5 bertrand 679: DosFreeMem(projection_fifos);
680: # endif
681: # else
1.1 bertrand 682: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
683: * sizeof(int));
684: # endif
685: return(-1);
686: }
687:
688: while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
689: free(nom);
690:
691: while(sem_wait(semaphore) != 0)
692: {
693: if (errno != EINTR)
694: {
695: # ifdef IPCS_SYSV
1.5 bertrand 696: # ifndef OS2
1.1 bertrand 697: shmdt(projection_fifos);
698: # else
1.5 bertrand 699: DosFreeMem(projection_fifos);
700: # endif
701: # else
1.1 bertrand 702: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
703: * sizeof(int));
704: # endif
705: return(-1);
706: }
707: }
708:
709: base = &(projection_fifos[(longueur_queue + 4) * queue]);
710: buffer = &(base[4]);
711:
712: // base[3] contient le nombre d'éléments restants
713:
714: if (base[3] <= 0)
715: {
716: sem_post(semaphore);
717: sem_close(semaphore);
718: # ifdef IPCS_SYSV
1.5 bertrand 719: # ifndef OS2
1.1 bertrand 720: shmdt(projection_fifos);
721: # else
1.5 bertrand 722: DosFreeMem(projection_fifos);
723: # endif
724: # else
1.1 bertrand 725: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
726: * sizeof(int));
727: # endif
728: return(-1);
729: }
730:
731: base[3]--;
732:
733: // base[1] contient le prochain élément à écrire
734:
735: buffer[base[1] + (nombre_queues * base[2])] = horodatage();
736: buffer[base[1]++] = (int) pid;
737: base[1] %= base[2];
738:
739: if (sem_post(semaphore) != 0)
740: {
741: # ifdef IPCS_SYSV
1.5 bertrand 742: # ifndef OS2
1.1 bertrand 743: shmdt(projection_fifos);
744: # else
1.5 bertrand 745: DosFreeMem(projection_fifos);
746: # endif
747: # else
1.1 bertrand 748: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
749: * sizeof(int));
750: # endif
751: sem_close(semaphore);
752: return(-1);
753: }
754:
755: sem_close(semaphore);
756:
757: // Fermeture des projections
758: # ifdef IPCS_SYSV
1.5 bertrand 759: # ifndef OS2
1.1 bertrand 760: shmdt(projection_fifos);
761: # else
1.5 bertrand 762: DosFreeMem(projection_fifos);
763: # endif
764: # else
1.1 bertrand 765: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
766: * sizeof(int));
767: # endif
768:
769: return(0);
770: }
771:
772: static inline int
773: chaine_markov(int markov, int delta)
774: {
775: double memoire = 0.9;
776: int valeur;
777:
778: valeur = (int) ((memoire * markov) + ((1 - memoire) * delta));
779: valeur = (valeur < 10) ? 10 : valeur;
780:
781: return(valeur);
782: }
783:
784: pid_t
785: origine_signal(int signal)
786: {
787: logical1 drapeau;
788:
789: int *base;
790: int *buffer;
791: int delta;
792: int pid;
793: int queue;
794:
795: queue = queue_de_signal(signal);
796:
797: BUG(queue == -1, uprintf("[%d] Unknown signal %d in this context\n",
798: (int) getpid(), signal));
799:
800: while(sem_wait(semaphores[queue]) != 0)
801: {
802: if (errno != EINTR)
803: {
804: return(-1);
805: }
806: }
807:
808: // On retire les interruptions anciennes qui ont été ratées sauf s'il
809: // s'agit de la dernière dans la queue.
810:
811: base = &(fifos[(longueur_queue + 4) * queue]);
812: buffer = &(base[4]);
813:
814: if (base[3] == (base[2] - 1))
815: {
816: delta = abs(horodatage() -
817: buffer[base[0] + (nombre_queues * base[2])]);
818: // Une seule interruption dans la queue.
819: pid = buffer[base[0]++];
820: base[0] %= base[2];
821: base[3]++;
822:
823: markov = chaine_markov(markov, delta);
824: }
825: else if (base[3] >= base[2])
826: {
827: // Aucune interruption n'est dans la queue.
828: // On a retiré trop d'interruptions de la queue.
829:
830: // (base[3] - base[2]) + 1 : nombre d'interruptions manquantes
831: // base[0] - 1 : dernière interruption lue
832: pid = buffer[((((base[0] + base[2] - 1) % base[2])
833: - ((base[3] - base[2]) + 1)) + base[2]) % base[2]];
1.4 bertrand 834:
835: if (kill(pid, 0) != 0)
836: {
837: pid = getpid();
838: }
1.1 bertrand 839: }
840: else
841: {
842: // Plusieurs interruptions à distribuer.
843: drapeau = d_vrai;
844:
845: do
846: {
847: delta = abs(horodatage() -
848: buffer[base[0] + (nombre_queues * base[2])]);
849: pid = buffer[base[0]++];
850: base[0] %= base[2];
851: base[3]++;
852:
853: if ((delta > (2 * markov)) && (base[3] < base[2]))
854: {
855: drapeau = d_vrai;
856: }
857: else
858: {
859: drapeau = d_faux;
860: }
861: } while(drapeau == d_vrai);
862:
863: markov = chaine_markov(markov, delta);
864: }
865:
866: if (sem_post(semaphores[queue]) != 0)
867: {
868: return(-1);
869: }
870:
871: return((pid_t) pid);
872: }
873:
874: int
875: kill_broken_siginfo(pid_t pid, int signal)
876: {
877: int ios;
878:
879: sem_t *semaphore;
880:
881: unsigned char *nom;
882:
883: /*
884: * Lorsqu'on veut interrompre le processus pid, on ouvre le segment
885: * correspondant au processus en question et ou ajoute le pid dans la
886: * queue.
887: *
888: * Le sémaphore global à tous les threads d'un même processus sert
889: * à garantir que les signaux seront traités dans l'ordre de ce qui est
890: * effectivement mis dans la queue.
891: */
892:
893: // Sémaphore acquis
894:
895: if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
896: {
897: return(-1);
898: }
899:
900: while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
901: free(nom);
902:
903: while(sem_wait(semaphore) != 0)
904: {
905: if (errno != EINTR)
906: {
907: return(-1);
908: }
909: }
910:
911: if ((signal != 0) && (signal != SIGINT))
912: {
913: if (queue_in(pid, signal) != 0)
914: {
915: sem_post(semaphore);
916: sem_close(semaphore);
917: return(-1);
918: }
919: }
920:
921: ios = kill(pid, signal);
922:
923: // Sémaphore relâché
924:
925: sem_post(semaphore);
926: sem_close(semaphore);
927:
928: return(ios);
929: }
930:
931: int
932: pthread_kill_broken_siginfo(pthread_t tid, int signal)
933: {
934: int ios;
935:
936: sem_t *semaphore;
937:
938: unsigned char *nom;
939:
940: if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
941: {
942: return(-1);
943: }
944:
945: while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
946: free(nom);
947:
948: while(sem_wait(semaphore) != 0)
949: {
950: if (errno != EINTR)
951: {
952: return(-1);
953: }
954: }
955:
956: if ((signal != 0) && (signal != SIGINT))
957: {
958: if (queue_in(getpid(), signal) != 0)
959: {
960: sem_post(semaphore);
961: sem_close(semaphore);
962: return(-1);
963: }
964: }
965:
966: ios = pthread_kill(tid, signal);
967:
968: sem_post(semaphore);
969: sem_close(semaphore);
970:
971: return(ios);
972: }
973:
974: #endif
975:
976: // vim: ts=4