2010-11-18 9 views
9

Ich habe glibc/nptls Implementierung von Abbruchpunkten untersucht und mit POSIX verglichen, und wenn ich mich nicht irre, ist es völlig falsch. Das Grundmodell verwendet wird:Wie sollen sich POSIX-Cancel-Punkte verhalten?

int oldtype = LIBC_ASYNC_CANCEL(); /* switch to asynchronous cancellation mode */ 
int result = INLINE_SYSCALL(...); 
LIBC_CANCEL_RESET(oldtype); 

Nach POSIX:

die Nebenwirkungen der auf eine Aufhebungsanforderung handeln während eines Anrufs einer Funktion sind die gleichen wie die Nebenwirkungen ausgesetzt, während das kann in einem Singlethread-Programm gesehen werden, wenn ein Aufruf einer Funktion durch ein Signal unterbrochen wird und die angegebene Funktion [EINTR] zurückgibt. Solche Nebenwirkungen treten auf, bevor Stornierungsaufräumhandler aufgerufen werden.

diese Passage Meine Lesart ist, dass wenn ich open nennen, ich kann es entweder erhalten abgesagt erwarten kann (zusammen mit meinem ganzen Thread), bevor er eine Datei nicht geöffnet wird, oder ein gültige zurückzukehren Dateideskriptor oder -1 und errno Wert, aber nie einen neuen Dateideskriptor zu erstellen, dann verlieren Sie es in die Leere. Auf der anderen Seite scheint die glibc/nptl-Implementierung von Abbruchpunkten eine Race-Bedingung zu ermöglichen, bei der die Abbruchanforderung auftritt, unmittelbar nachdem der Syscall zurückkehrt, aber bevor LIBC_CANCEL_RESET stattfindet.

Bin ich verrückt, oder ist ihre Umsetzung wirklich so kaputt? Und wenn ja, erlaubt POSIX ein solches kaputtes Verhalten (was die Annullierung vollständig unbrauchbar macht, wenn Sie es nicht manuell verschieben), oder ignorieren sie POSIX schlicht und einfach?

Wenn dieses Verhalten tatsächlich gebrochen ist, was ist der richtige Weg, um es ohne eine solche Race Condition zu implementieren?

Antwort

4

Ist das nicht im nächsten Absatz des Standard geklärt:

Wenn jedoch der Faden bei einem Aufhebungspunkt aufgehängt ist und das Ereignis für die es auftritt, bevor der Löschungsantrag wartet Wird gehandelt, ist nicht angegeben, ob die Stornierungsanfrage bearbeitet wird oder , ob die Stornierungsanfrage weiterhin aussteht und der Thread normale Ausführung wieder aufnimmt.

Was bedeutet, dass diese Race-Bedingung ist völlig legales Verhalten.

+3

Wie schreibt man ein robustes Programm mit solch unsinnigem Verhalten? Es sieht so aus, als müssten Sie jeden Anruf auf "open" (und andere Cancellation-Punkte, die Ressourcen zuweisen können) mit Code einbinden, um die Löschung zu deaktivieren, die Deaktivierung immer deaktiviert und 'pthread_trycancel' manuell aufzurufen oder einen Weg zu finden Suchen und Freigeben solcher Ressourcen (für Dateideskriptoren ist es möglich, alle Werte zu durchlaufen, aber ziemlich gefährlich, dies in einer Anwendung mit Gewinde ohne einige schwere Sperren zu tun). –

+1

mmh, ich habe gelesen, dass der Thread gerade noch nicht abgebrochen werden kann und beim nächsten Cancellation-Punkt abgebrochen werden sollte (In diesem Fall benötigen die Cancelling Points die Unterstützung des Betriebssystems und sind wahrscheinlich in der Art gebrochen, wie R. sagt die meisten Betriebssysteme). – ninjalj

+0

@ninjaj: Ich denke cmeerw kann richtig sein. Die Passage besagt, dass, wenn (zum Beispiel) der Thread suspendiert ist und auf "open" wartet, um zurückzukehren, aber "open" seine Arbeit bereits beendet hat, könnte die Implementierung die Löschung erlauben oder lassen. –

Verwandte Themen