RE: select() failure
This can arise if you do one of the operations threadWaitRead or threadWaitWrite on a file descriptor that is closed. Sigbjorn recently modified the select() code so that it wouldn't fail in such an ugly way; now it just wakes up all the threads that were doing select() in the hope that the one with a bad file descriptor in its hands will discover it some other way (the real problem is that select() doesn't tell us which file desriptors were bad/closed when it fails). Anyway, you should avoid this scenario if at all possible, since the current fall-back method of waking up all the threads could be quite expensive. I use `threadWaitRead` in one place and `threadWaitWrite` nowhere. I added a check before the use of `threadWaitRead` that I've not closed the file descriptor. The check never detects a closed file descriptor, yet I still get the select() failure. Hmm, then I don't know what is going wrong. Perhaps you could reduce it to a small example and post it? I'm assuming that the RTS's select() is done on the sets of file descriptors involved in current `threadWaitRead` and `threadWaitWrite` calls. Is that true? Are there other uses of select() in the RTS? No, that's the only select() call. Unfortunately, select() (and hence the GHC RTS) doesn't identify the bad descriptor(s). Here's where I suspect my program may be going awry. The main process creates a pipe. The process then forks. The parent closes the pipe's read descriptor immediately. The child soon goes to read from the pipe, using threadWaitRead followed by fdRead. The child process suffers the select failure shown above. So.. I take it the child shouldn't really be reading from a closed file descriptor? The file descriptor is the read end of a pipe used to send data from the parent to the child. The parent closes it because it will never use it, but only after the parent forks. So the child's copy of the file descriptor should still be open, n'est-ce pas? Yes, seems reasonable to me. Are there any other file descriptors that you are closing? Are you doing any lazy I/O? By the way, why shouldn't such a fatal error in the RTS raise an exception that I can catch in my program? I could then determine at least which thread in which process suffered the error. A 'fatal error' in the RTS usually means some kind of internal error which it isn't possible to recover from. Hence the term fatal :-) I've changed the wording in my copy to make it more clear that these errors are internal and normally indicate a bug. Is recovering from this error really not possible, as opposed to not likely to be useful? Recovery is possible; as I mentioned the latest code in the HEAD does recover. Reporting an error is somewhat impractical, however, because select() doesn't tell us which of the file descriptors was bad. Cheers, Simon ___ Glasgow-haskell-bugs mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
RE: (fwd) FranTk with ghc-5.04
Good point. Fixed, and will be in 5.04.1 Thanks for reporting this. Simon | -Original Message- | From: Oliver Braun [mailto:[EMAIL PROTECTED]] | Sent: 23 August 2002 11:59 | To: [EMAIL PROTECTED] | Subject: (fwd) FranTk with ghc-5.04 | | | Hi Meurig, | | I am currently working on a FranTk port for FreeBSD. | FranTk1_1.tar.gz worked perfectly with ghc-5.02, but with | ghc-5.04 I get: | | ghc --make FranTkSrc/FranTk.lhs -fvia-C -fglasgow-exts | -fallow-overlapping-instances -fallow-undecidable-instances | -package concurrent -package data -package-name FranTk | -iTclHaskellSrc -iFRPSrc -iFRPSrc/StaticTypes | -iFRPSrc/BehaviorTypes -iFRPSrc/FRPImpl -iFranTkSrc | ghc-5.04: chasing modules from: FranTkSrc/FranTk.lhs | ... | snip | ... | Compiling GUIDef ( FranTkSrc/GUIDef.lhs, | FranTkSrc/GUIDef.o ) | | FranTkSrc/GUIDef.lhs:98: Warning: Pattern match(es) are overlapped | In the definition of `identify': identify _ = ... | stack overflow: use +RTS -Ksize to increase it | gmake: *** [FranTkSrc/FranTk.o] Error 1 | *** Error code 2 | | after applying the attached patches. Exactly the same happens | when using | +RTS -50M. | | Regards, | Olli | -- | : IST IIS _ INF _ UniBwM :: | [EMAIL PROTECTED] : | : Tele-Consulting GmbH :: [EMAIL PROTECTED] | : | : FreeBSD Commmitter :: [EMAIL PROTECTED] | : | ___ Glasgow-haskell-bugs mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
RE: stack overflow
This is the same problem as was causing GHC 5.04 to go into a loop on FranTk. It's now fixed in the repository and the fix will be in 5.04.1. Meanwhile use 5.02! Thanks for the report Simon | -Original Message- | From: Nobuo Yamashita [mailto:[EMAIL PROTECTED]] | Sent: 16 August 2002 01:24 | To: [EMAIL PROTECTED] | Subject: stack overflow | | | Dear Implementors | | I got strange behavior of ghc-5.04 on my linux box. | | I got WASH-CGI.tgz from | | http://www.informatik.uni-freiburg.de/~thiemann/haskell/WASH/W | ASH-CGI.tgz | Then expanded and tyied to make a sample | Examples/HellowWorld.hs. The ghc-5.04 stoped on compiling | ../CGIInternals and told me to increase stack size. I set | stack size 16m and 160m but was not able to compile it. | | I tried also with ghc-5.02.3. So he can compile that code | without increasing stack size. | | -- | Nobuo Yamashita mailto:[EMAIL PROTECTED] ___ Glasgow-haskell-bugs mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Re: select() failure
Simon Marlow wrote: Unfortunately, select() (and hence the GHC RTS) doesn't identify the bad descriptor(s). Here's where I suspect my program may be going awry. The main process creates a pipe. The process then forks. The parent closes the pipe's read descriptor immediately. The child soon goes to read from the pipe, using threadWaitRead followed by fdRead. The child process suffers the select failure shown above. So.. I take it the child shouldn't really be reading from a closed file descriptor? The file descriptor is the read end of a pipe used to send data from the parent to the child. The parent closes it because it will never use it, but only after the parent forks. So the child's copy of the file descriptor should still be open, n'est-ce pas? Yes, seems reasonable to me. Are there any other file descriptors that you are closing? Are you doing any lazy I/O? Yes and yes. Your questions suggest a new hypothesis which I'll mention here for your thoughts and, in parallel, test out on my program. Suppose the parent process has a thread blocked on `threadWaitRead` at the time it forks. In the new process, the file descriptor on which that thread is waiting is closed. The next select() call fails because one of the designated file descriptors is now invalid. If the above hypothesis is true, then my schemes for cleaning up unwanted file descriptors and threads in the new process are not playing together well enough. To clean up unwanted file descriptors, I keep track of open file descriptors in the parent process and close unwanted ones in the child process. To clean up unwanted threads, I have a thread obtain and hold a process-wide lock while performing a side-effecting operation; in a forked child process, the lock tells preexisting threads to commit suicide instead of performing their side-effecting operation. When a thread wants to read from a file descriptor, its logic looks like: threadWaitRead (fdToInt fd) ([char], 1) - locked (fdRead fd 1) where `locked` obtains and holds the aforementioned lock for the duration of its argument action. Reflecting on the above, I now realize that the recent change (/fptools/ghc/rts/Select.c?rev=1.22 in GHC 5.04) to wake up all threads when select() returns an EBADF error, though well-intentioned, is inappropriate. The point of `threadWaitRead` and `threadWaitWrite` is to block the calling thread until it's known that a subsequent call involving the given file descriptor will not block. Allowing all threads to continue--even those whose file descriptor is not yet ready--allows for exactly the deadlock that `threadWaitRead` and `threadWaitWrite` are designed to avoid. I consider it a bug in select() that, when EBADF is reported, the sets of ready file descriptors are not also reported. Fortunately, I think select() can be fixed (albeit clumsily) in the GHC RTS. When EBADF is reported, cycle through all file descriptors that were presented to select(), invoking select() with each single file descriptor (and with zero timeout). At least one of these calls should report EBADF; wake up the threads corresponding to all such calls. (It's probably worth waking up threads corresponding to normal returns from select(), too, while you're at it.) Using select() as just described would regain for `threadWaitRead` and `threadWaitWrite` their necessary semantic guarantee. I think it would also solve my problem. In the meantime, I will investigate killing unwanted threads with `killThread` in the child process, before closing unwanted file descriptors, which should avoid occurrences of EBADF from select(). It sure would simplify my program if I could fork a process and not have auxiliary threads persist in the child. Could this option be provided by GHC RTS in a semantically sound way? Thanks for asking the right questions! Dean ___ Glasgow-haskell-bugs mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Re: select() failure
Dean Herington [EMAIL PROTECTED] writes: ... When a thread wants to read from a file descriptor, its logic looks like: threadWaitRead (fdToInt fd) ([char], 1) - locked (fdRead fd 1) where `locked` obtains and holds the aforementioned lock for the duration of its argument action. Reflecting on the above, I now realize that the recent change (/fptools/ghc/rts/Select.c?rev=1.22 in GHC 5.04) to wake up all threads when select() returns an EBADF error, though well-intentioned, is inappropriate. The point of `threadWaitRead` and `threadWaitWrite` is to block the calling thread until it's known that a subsequent call involving the given file descriptor will not block. Allowing all threads to continue--even those whose file descriptor is not yet ready--allows for exactly the deadlock that `threadWaitRead` and `threadWaitWrite` are designed to avoid. The assumption is that FDs are marked as non-blocking, so this won't be a problem. Do you have a good reason not to have your FDs marked as such? I consider it a bug in select() that, when EBADF is reported, the sets of ready file descriptors are not also reported. That would be the wrong thing to do, assuming the FD_SETs are in any way valid when select() returns failure. --sigbjorn ___ Glasgow-haskell-bugs mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Re: select() failure
In local.glasgow-haskell-bugs, you wrote: It sure would simplify my program if I could fork a process and not have auxiliary threads persist in the child. Could this option be provided by GHC RTS in a semantically sound way? On a recent GHC you can try 'forkProcess[Prim]': http://www.haskell.org/ghc/docs/latest/html/base/GHC.Conc.html#forkProcessPrim -- plonk :: m a - m () http://www-i2.informatik.rwth-aachen.de/stolz/ *** PGP *** S/MIME ___ Glasgow-haskell-bugs mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Re: select() failure
Sigbjorn Finne wrote: Dean Herington [EMAIL PROTECTED] writes: ... When a thread wants to read from a file descriptor, its logic looks like: threadWaitRead (fdToInt fd) ([char], 1) - locked (fdRead fd 1) where `locked` obtains and holds the aforementioned lock for the duration of its argument action. Reflecting on the above, I now realize that the recent change (/fptools/ghc/rts/Select.c?rev=1.22 in GHC 5.04) to wake up all threads when select() returns an EBADF error, though well-intentioned, is inappropriate. The point of `threadWaitRead` and `threadWaitWrite` is to block the calling thread until it's known that a subsequent call involving the given file descriptor will not block. Allowing all threads to continue--even those whose file descriptor is not yet ready--allows for exactly the deadlock that `threadWaitRead` and `threadWaitWrite` are designed to avoid. The assumption is that FDs are marked as non-blocking, so this won't be a problem. Do you have a good reason not to have your FDs marked as such? One reason is complexity. If I mark my FDs with O_NONBLOCK, don't I need to wrap a loop around the `threadWaitRead`/`fdRead` combination, repeating when `fdRead` returns error `EAGAIN`? A second reason is that, even if I did the above, I'd still get deadlock on my `locked` call (which is required to support cleaning up unwanted threads in forked processes). The bottom line, in my view, is that `threadWaitRead` and `threadWaitWrite` must not return until it is sure that a subsequent read or write FD operation will return immediately, independent of the nonblocking status of the FD. I consider it a bug in select() that, when EBADF is reported, the sets of ready file descriptors are not also reported. That would be the wrong thing to do, assuming the FD_SETs are in any way valid when select() returns failure. I don't understand your comment. I fear I wasn't clear enough. I meant that it would be better for select() to identify the FDs which are invalid in the case it returns `EBADF`. Then the clumsy code I suggested would not be necessary. Dean ___ Glasgow-haskell-bugs mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
killThread doc bug
http://www.haskell.org/ghc/docs/latest/html/base/GHC.Conc.html says: The killThread function may be defined in terms of throwTo: killThread = throwTo (AsyncException ThreadKilled) I think it should be: killThread = flip throwTo (AsyncException ThreadKilled) or, perhaps better: killThread tid = throwTo tid (AsyncException ThreadKilled) ___ Glasgow-haskell-bugs mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Sayýn glasgow-haskell-bugs ,
Title: Green Card Amerika çekiliþi için son bir ay! Yakalanmayacak bir fýrsat, Amerika'da hayat boyu oturma ve çalýþma izni edinmek Green Card'dan geçiyor. Bir daha bu tip bir çekiliþ gelecek senelerde olmayabilir, bu þansý kaçýrmayýn hemen týklayýn. Baþvurmak için lise son veya lise mezunu olmanýz yeterli, Ýngilizce bilmeniz kesinlikle gerekmiyor. Green Card sahipleri; 1. Amerika Birleþik Devletleri'nde süresiz olarak (hayat boyu) oturma ve çalýþma iznine sahiptirler. 2. Amerikan vatandaþlýk haklarýndan birçoðuna sahip olurlar. 3. Kartý aldýktan beþ sene sonra isterlerse A.B.D. vatandaþlýðý baþvurusu yapabilirler. 4. Ýþyeri açma imkanýna sahip olurlar. 5. Devlet üniversitelerine burs baþvurusu yapabilme imkaný. 6. Devlet Dairelerinde çalýþabilme imkaný. Sadece baþvuru formumuzu doldurmanýz yeterli, adýnýza doldurulmuþ olarak gelen formlarý imzalayýp siz kendiniz Amerika'ya normal posta ile yollayýn ve baþvurunuzun yapýldýðýndan emin olun. ( Amerika'ya gönderi bedeli sadece 600.000 T.L.'dir .) Saygýlarýmýzla, www.abdyesilkart.com E-posta grubundan ayrýlmak ve bir daha e-posta almamak için buraya týklayýn ___ Glasgow-haskell-bugs mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs