Ich arbeite an der Implementierung von pthread cancellation unter Linux ohne das "unangenehme Verhalten" (einige sagen Bugs), das in einigen meiner letzten Fragen diskutiert wurde. Der Linux / glibc-Ansatz zur Entfernung von pthread war bislang so, dass er als etwas behandelt wird, das keine Kernel-Unterstützung benötigt und auf der Bibliotheksebene allein dadurch behandelt werden kann, dass die asynchrone Löschung vor dem Syscall aktiviert wird und der vorherige Löschungszustand wiederhergestellt wird nachdem der syscall zurückkehrt. Dies hat mindestens zwei Probleme, von denen eines sehr ernst ist:
Meine erste Idee zur Behebung des Problems bestand darin, ein Flag zu setzen, dass der Thread an einem Cancellation-Punkt ist, anstatt Async-Cancellation zu aktivieren. Wenn dieses Flag gesetzt ist, überprüft der Cancellation-Signal-Handler den gespeicherten Befehlszeiger Es zeigt auf eine syscall-Anweisung (arch-spezifisch). Wenn dies der Fall ist, zeigt dies an, dass der Syscall nicht abgeschlossen wurde und bei Rückkehr des Signalhandlers neu gestartet würde, so dass wir abbrechen können. Wenn nicht, nahm ich an, dass der Syscall bereits zurückgekommen war, und dass die Kündigung verschoben wurde. Es gibt jedoch auch eine Race-Bedingung - es ist möglich, dass der Thread den syscall-Befehl überhaupt noch nicht erreicht hat. In diesem Fall könnte der syscall blockieren und niemals auf den Abbruch reagieren. Ein weiteres kleines Problem besteht darin, dass nicht abbrechbare Syscalls, die von einem Signal-Handler ausgeführt wurden, fälschlicherweise gelöscht werden konnten, wenn das Flag für den Löschpunkt beim Eingeben des Signal-Handlers gesetzt wurde.
Ich schaue mir einen neuen Ansatz an und suche nach einem Feedback dazu. Die Bedingungen, die erfüllt sein müssen:
Die Idee, die ich mir vorstelle, erfordert eine spezielle Assembly für den abbrechbaren Syscall-Wrapper. Die Grundidee wäre:
Der Abbruchvorgang würde dann beinhalten:
Der Stornosignal-Handler würde dann:
Das einzige Problem, das ich bisher gesehen habe, ist in Schritt 1 des Signal-Handlers: Wenn es sich entscheidet, nicht zu handeln, dann kann der Thread nach dem Zurücksenden des Signal-Handlers auf dem Syscall blockiert werden, wobei die anstehende Abbruchanforderung ignoriert wird. Dafür sehe ich zwei mögliche Lösungen:
Irgendwelche Gedanken darüber, welche Herangehensweise am besten ist, oder wenn es noch grundlegendere Fehler gibt, die mir fehlen?
Lösung 2 fühlt sich weniger wie ein Hack an. Ich denke nicht, dass dies das von Ihnen vorgeschlagene Problem verursachen würde, da abbrechbare Syscalls, die innerhalb des syscall-Handlers aufgerufen werden, das Löschungsflag in TLS prüfen, das bereits gesetzt wurde, wenn der Cancelling-Signal-Handler sowieso mit der Signalmaske gelaufen ist.
(Es scheint, als wäre es viel einfacher für Implementierer, wenn jeder blockierende Systemaufruf einen sigmask
-Parameter a la pselect()
benötigt).
Tags und Links c linux pthreads posix cancellation