2012-12-28 6 views
5

Ich schreibe eine Haskell-Bindung an einige der Bibliothek und es gibt eine Funktion void foo(), die select() innerhalb ruft. Wenn ich diese Funktion von Haskell anrufe, beginnt der select() Aufruf ständig EINTR zurückzukehren. Dies verwirrt den Bibliothekscode und es beginnt für immer zu loopen.Schnittstelle mit dem Code, der ruft select()

Im #haskell IRC-Kanal wurde mir gesagt, foo() von einem gebundenen Thread zu laufen. Ich habe runInBoundThread dafür verwendet und jetzt scheint alles zu funktionieren. Aber in einigen seltenen Fällen bekomme ich Alarm clock Nachricht in der Konsole (Ok, ich habe gefunden, bedeutet, dass App SIGALRM fängt).

Ich bin mir nicht sicher, es ist richtige Weise, um dieses Problem zu behandeln, und ich möchte nicht auf Control.Concurrency abhängen. Was soll ich machen?

+0

'Control.Concurrent' Teil der Standardbibliothek ist - je nach ihm der gleichen wie in Abhängigkeit von Haskell ist. Warum willst du dieses Modul nicht benutzen? (Obwohl ich zugeben muss, dass die Alarmmeldungen seltsam sind, habe ich das nie gesehen) – luqui

+6

Ich höre GHC verwendet intern SIGALRM und SIGVTALRM für Thread-Management. Wenn der fremde Code-Thread für diese Signale empfindlich ist, sollten Sie sie für diesen Thread blockieren. Siehe z.B. 'withRTSSignalsBlocked' von' Database.HDBC.MySQL.RTS'. –

Antwort

2

Die Ursache von SIGALRM war die Laufzeit von GHC, die einen alten Codepath zur Verwaltung von Timer-Daten verwendete. Dieser alte Codepath wurde aktiviert, weil das GHC configure-Skript bei der Prüfung auf create_timer() eine Art von Linux-Funktion hatte. Durch die Korrektur hat GHC denselben Mechanismus verwendet, der auf allen Plattformen verwendet wird, und den Fehler beseitigt.

Relevante Phabricator Diff: https://phabricator.haskell.org/D831

1

n.m. Kommentar ist richtig: der Code in withRTSSignalsBlocked werden verbergen Signale von Ihrem ffi'd Code: http://hackage.haskell.org/packages/archive/HDBC-mysql/0.6.6.1/doc/html/Database-HDBC-MySQL.html#v:withRTSSignalsBlocked

Dies sollte auch die Notwendigkeit runInBoundThread beseitigen, denke ich.

+0

'withRTSSignalsBlocked act = runInBoundThread. alloca $ \ set -> do ... 'Hmm ... okay, ich werde es trotzdem versuchen. – arrowd

+0

Das hat mir nicht geholfen. Wenn ich "runInBoundThread" und "pthread_sigmask" auf "rhs" von "finally" verwerfe, funktioniert es. Aber es ist völlig falsch, wenn ich es richtig verstehe. – arrowd

+0

Dann ist die Aktion, die Sie aufrufen, die von rTSSignalsBlocked überwacht wird, nicht die, die den Fehler verursacht, oder es tut irgendwie etwas mit trägem IO. d. h. das Blockieren der Signale funktioniert, aber sie werden irgendwo anders gefangen als beim Ausführen der Aktion. – sclv

Verwandte Themen