
Hello glasgow-haskell-users, my program contaions several forkOSed threads and at one moment one thread gives to another handle of open file. i need to read some data from this file. how can i accomplish this? if i use hDuplicate, then both handles will share the same file pointer, so threads will mess each other. are there some way to duplicate handle with creating separate file pointer, or to get filename from the Handle, or (preferable) to block another thread's on attempt to access the same handle until i done with it and return to old file pointer? -- Best regards, Bulat mailto:bulatz@HotPOP.com

Bulat Ziganshin writes:
one thread gives to another handle of open file. i need to read some data from this file. how can i accomplish this?
Keep the Handle in an MVar at all times, then access to it will be synchronized between threads: http://haskell.org/ghc/docs/latest/html/libraries/base/Control.Concurrent.MV... If you need more background on this stuff, this paper is the one you want to read: http://research.microsoft.com/Users/simonpj/papers/marktoberdorf/ Peter

Hello Peter, Sunday, May 15, 2005, 4:07:28 PM, you wrote: PS> http://research.microsoft.com/Users/simonpj/papers/marktoberdorf/ this article says that -------------------------------------------------- some foreign procedures may cover have purelyfunctional semantics. For example, the C sin function really is a function: it has no side effects. In this case it is extremely tiresome to force it to be in the IO monad. So the Haskell FFI allows one to use the unsafe keyword, and omit the ``IO'' from the return type, thus: foreign import ccall unsafe sin :: Float > Float As in the case of unsafePerformIO (Section 2.6), ``unsafe'' indicates that the programmer takes on a proof obligation, in this case that foreign procedure is genuinely functional. -------------------------------------------------- while the FFI specification state that -------------------------------------------------- Optionally, an import declaration can specify, after the calling convention, the safety level that should be used when invoking an external entity. A safe call is less efficient, but guarantees to leave the Haskell system in a state that allows callbacks from the external code. In contrast, an unsafe call, while carrying less overhead, must not trigger a callback into the Haskell system. If it does, the system behaviour is undefined. The default for an invocation is to be safe. Note that a callback into the Haskell system implies that a garbage collection might be triggered after an external entity was called, but before this call returns. Consequently, objects other than stable pointers (cf. Section 5.6) may be moved or garbage collected by the storage manager. -------------------------------------------------- and one more question: is it possible to download sources of http server mentioned in this article? i want to browse the code, it's no matter how it compiles and works -- Best regards, Bulat mailto:bulatz@HotPOP.com

Bulat, just for the record, it's not my article. Although I have the privilege of sharing a somewhat similar name with the geniuses around here, I didn't have any part in that text. ;-) You were wondering about this declaration:
foreign import ccall unsafe sin :: Float -> Float
I guess you are confused by the difference between safe/unsafe FFI calls versus pure/impure FFI calls. Which is comforting for me, because as it happens I don't quite understand that either. ;-) I'll try to explain what I believe I do understand, and hope that the others on this list chime in case I mess something up. A pure function is one without side-effects, meaning that the result depends only on the function arguments. Those are surprisingly few; the C function strlen(3) for example is _not_ pure because it depends on the fact that the memory pointed to by the argument actually contains the string which's length you'd like to compute. So the strlen() call must occur in the correct order in relation to other I/O calls like as read(), malloc(), or whatever. Thus, the signature for strlen() would be: strlen :: Ptr CChar -> IO CSize The sin(3) function on the other hand is pure. It doesn't depend on anything but the floating point value you give it, hence in can be evaluated at any point of the program execution, hence it doesn't need to be in the IO monad: sin :: CFloat -> CFloat Now, safe and unsafe calls are a different beast: | A safe call is less efficient, but guarantees to leave the | Haskell system in a state that allows callbacks from the | external code. In contrast, an unsafe call, while carrying | less overhead, must not trigger a callback into the Haskell | system. The vast majority of C function you will call are unaware of Haskell. They will not trigger anything the Haskell runtime system needs to know about, nor will they force a part of your Haskell program to be evaluated. Those functions can be called unsafely, just like the definition above says. Since pure FFI calls don't have any side-effects, they are always safe to be called unsafely. (Yes, the choice of the words "safe" and "unsafe" is a bit unfortunate in the standard here.) So unless I am very mistaken, the declaration foreign import ccall safe sin :: Float -> Float would work just as well as the one above does, but it would be less efficient. In other words, if you declare a FFI function to be called safely, and to be called from within the IO monad, then absolutely nothing can possibly go wrong. ;-)
is it possible to download sources of http server mentioned in this article?
I think the (more or less) latest version is here: http://www.mdstud.chalmers.se/~md9ms/hws-wp/ Another somewhat extensive example for system programming in Haskell is available here: http://postmaster.cryp.to/ Hope this helps. Peter

On Fri, 2005-05-20 at 11:30 +0200, Peter Simons wrote:
Since pure FFI calls don't have any side-effects, they are always safe to be called unsafely. (Yes, the choice of the words "safe" and "unsafe" is a bit unfortunate in the standard here.)
To try and undo this confusion we need to recall what the safe/unsafe are referring to. This safe/unsafe tag is used to describe both a property of the form of the call (what degree of precaution we take in making the call) and also a property of the thing we are calling (whether it has side effects or can trigger callbacks into the Haskell world). The two uses are basically opposite: For a C procedure that can trigger callbacks, we have to take extra procautions when calling it, that is we have to make the call in a "safe" way. For a C procedure that cannot trigger callbacks, we don't have to worry at all when calling it, that is we can omit various cleanups, locks and checks thus doing the call in an "unsafe" way. So to sumarise the pairings: * you _must_ make a safe call to an unsafe foreign function * you _may_ make an unsafe call to a safe foreign function It's a contravariance :-) Duncan

Duncan Coutts writes:
So to sumarise the pairings: * you _must_ make a safe call to an unsafe foreign function * you _may_ make an unsafe call to a safe foreign function
It's a contravariance :-)
I'd use a slightly different term. Declaring a function that needs special precaution to be called as "safe", and declaring a function that is safe to be called anytime as "unsafe" is contra-intuitive. ;-) Peter

Hello Peter, Friday, May 20, 2005, 1:30:08 PM, you wrote: PS> just for the record, it's not my article. Although I have the PS> privilege of sharing a somewhat similar name with the geniuses PS> around here, I didn't have any part in that text. ;-) i answered your letter but wrote to Simon PJ PS> Since pure FFI calls don't have any side-effects, they are PS> always safe to be called unsafely. sorry, but even pure C function can call back to Haskell world and lead to GC. so the meaning of "IO" and "unsafe" are completely orthogonal. moreover, 90% of called C fucntions will not call back to Haskell, whether they in IO monad or not -- Best regards, Bulat mailto:bulatz@HotPOP.com

Bulat Ziganshin writes: PS> Since pure FFI calls don't have any side-effects, they are PS> always safe to be called unsafely.
sorry, but even pure C function can call back to Haskell world and lead to GC.
Um, right. I said I didn't understand these things completely either. Guess I was right. ;-)
participants (3)
-
Bulat Ziganshin
-
Duncan Coutts
-
Peter Simons