RE: Are handles closed automatically when they fall out of scope?

2004-10-25 Thread Simon Marlow
On 22 October 2004 21:58, Peter Simons wrote:

 I know it's a rather mundane question, but I couldn't find
 an answer to it!
 
 So what does happen when I forget to hClose a Handle? Will
 the garbage collector do that for me? Or not?

Yes, a Handle will be automatically closed sometime after it becomes
unreferenced.  However, the party line is don't rely on this
behaviour, because it is inherently unpredictable, and if you get it
wrong you can end up running out of file descriptors.  hClose explicitly
when you can.

 And more specifically, what about the handles
 runInteractiveProcess returns? Do I have to close the
 stdin Handle? All of them? What happens when I use
 terminateProcess? Do I have to hClose them nonetheless?

The stdin handle is attached to a pipe, and you get the behaviour you
expect when you close the write end of a pipe: if a process tries to
read the other end of the pipe, it will get EOF.  After
terminateProcess, if you write to the stdin handle, you're likely to get
SIGPIPE on Unix.

(BTW, I assume you have a good reason for wanting to call
terminateProcess).

 And while I am at it: How about Socket? Do I have to sClose
 a socket I obtained from listenOn or accept?

A Socket isn't finalized automatically (that is, you need explicit
sClose). However, if you use socketToHandle, then the Handle will be
finalized, and hence the socket closed, when it becomes unreachable.

On 24 October 2004 23:37, John Goerzen wrote:

 * What happens when one Handle corresponding to a socket is closed,
   but another isn't?

You shouldn't have two Handles on the same socket.  This is an unchecked
error.

 * What happens when one gets GC'd but another doesn't?

See above.

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Are handles closed automatically when they fall out of scope?

2004-10-25 Thread Peter Simons
Simon Marlow writes:

  BTW, I assume you have a good reason for wanting to call
  terminateProcess

Yes, I have to abort the process in case of an exception in
my code. Just giving it EOF is not enough, unfortunately.

Thanks a lot for taking the time to answer, Simon. I really
appreciate it.

Peter


P. S.: It might be worth adding a few sentences to the
description of 'Handle' which explain these problems. I'm
certain other users of the language will run into the same
questions.

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Are handles closed automatically when they fall out of scope?

2004-10-25 Thread John Goerzen
On 2004-10-25, Simon Marlow [EMAIL PROTECTED] wrote:
 On 22 October 2004 21:58, Peter Simons wrote:

 On 24 October 2004 23:37, John Goerzen wrote:

 * What happens when one Handle corresponding to a socket is closed,
   but another isn't?

 You shouldn't have two Handles on the same socket.  This is an unchecked
 error.

This does seem useful, though.  I am actually doing this in my code and
it works.  One Handle is opened ReadOnly, the other WriteOnly.  That
way, I can use hGetContents on the reading side in my network code.

If I tried that with a single Handle opened ReadWrite, then I'd get
errors about it being closed whenever I'd try to write out some data.

I wasn't able to find any other good way around it.

-- John


___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: Are handles closed automatically when they fall out of scope?

2004-10-25 Thread Simon Marlow
On 25 October 2004 14:24, John Goerzen wrote:

 On 2004-10-25, Simon Marlow [EMAIL PROTECTED] wrote:
 On 22 October 2004 21:58, Peter Simons wrote:
 
 On 24 October 2004 23:37, John Goerzen wrote:
 
 * What happens when one Handle corresponding to a socket is closed,
   but another isn't?
 
 You shouldn't have two Handles on the same socket.  This is an
 unchecked error.
 
 This does seem useful, though.  I am actually doing this in my code
 and it works.  One Handle is opened ReadOnly, the other WriteOnly. 
 That way, I can use hGetContents on the reading side in my network
 code. 
 
 If I tried that with a single Handle opened ReadWrite, then I'd get
 errors about it being closed whenever I'd try to write out some data.
 
 I wasn't able to find any other good way around it.

Hmmm, you should still be able to *write* to a socket handle that has
had hGetContents applied to it.  In GHC, a ReadWrite handle to a socket
basically consists of a wrapper around two independent Handles, one for
read and one for write, each with its own buffer.

... I just tested it with 6.2.2, and indeed it does work as I expected.
But perhaps there's a bug lurking somewhere?

If you do socketToHandle twice, then the danger is that one of the
Handles will be finalized and close the FD before the other Handle has
finished with it.

In 6.4 you'll be able to use hDuplicate for this, BTW.

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Are handles closed automatically when they fall out of scope?

2004-10-25 Thread John Goerzen
On 2004-10-25, Simon Marlow [EMAIL PROTECTED] wrote:
 If I tried that with a single Handle opened ReadWrite, then I'd get
 errors about it being closed whenever I'd try to write out some data.
 
 I wasn't able to find any other good way around it.

 Hmmm, you should still be able to *write* to a socket handle that has
 had hGetContents applied to it.  In GHC, a ReadWrite handle to a socket
 basically consists of a wrapper around two independent Handles, one for
 read and one for write, each with its own buffer.

You were right.  Long story, but I had a different bug that happened to
get fixed at the same time.

Which brings up another question:

The problem was that I was trying to *read* using hGetContents more than
once.  I have this data structure:

data FTPConnection = FTPConnection {readh :: IO String,
writeh :: Handle,
socket_internal :: Socket,
isPassive :: Bool}

Now, if I set readh to to be hGetContents h, then the first read I try to
make using it works, but subsequent ones don't, since the first one made
it half-closed already.

If I make readh a plain string, instead of an IO String, then each time
I try to read from it, I start back at the very beginning -- reading the
same response from the network over and over, in other words.

In this case, my workaround was to write my own simple version of
hGetContents that uses hGetChar and doesn't make anything half-closed.

Maybe there's a better way?

 If you do socketToHandle twice, then the danger is that one of the
 Handles will be finalized and close the FD before the other Handle has
 finished with it.

In this particular case, my data structure is opaque, so nobody else
will be able to access the underlying handles.  But thanks for the
caution -- I will be sure to remember that.

-- John

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Are handles closed automatically when they fall out of scope?

2004-10-25 Thread Peter Simons
John Goerzen writes:

  Now, if [I read with hGetContents h], then the first read
  I try to make using it works, but subsequent ones don't,
  since the first one made it half-closed already.

Maybe I misunderstood something ... but why do you need to
read from the stream multiple times after calling
hGetContents? The function returns the _entire_ (lazily
evaluated) input stream, there is no need to read again. You
already _have_ everything.

Peter

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Are handles closed automatically when they fall out of scope?

2004-10-25 Thread John Goerzen
On 2004-10-25, Peter Simons [EMAIL PROTECTED] wrote:
 John Goerzen writes:

  Now, if [I read with hGetContents h], then the first read
  I try to make using it works, but subsequent ones don't,
  since the first one made it half-closed already.

 Maybe I misunderstood something ... but why do you need to
 read from the stream multiple times after calling
 hGetContents? The function returns the _entire_ (lazily
 evaluated) input stream, there is no need to read again. You
 already _have_ everything.

Because I'd have to use a state monad or something to chop off the top
of the list each time I read from it.  This is a FTP client module, so,
for instance, you might see this session:

cwd h /pub/linuc
nlst h Nothing

etc.

Each command sends something and reads a reply.  h holds an instance
of that data structure I posted.

If I just try to read from the list during each command, I would just
read the same (first) response over and over again.  Or, I'd have to
store a position (which also requires a state monad), which would lead
to wasting memory keeping all that stuff around.


___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Are handles closed automatically when they fall out of scope?

2004-10-25 Thread David Brown
On Mon, Oct 25, 2004 at 09:42:13PM +, John Goerzen wrote:

  Maybe I misunderstood something ... but why do you need to
  read from the stream multiple times after calling
  hGetContents? The function returns the _entire_ (lazily
  evaluated) input stream, there is no need to read again. You
  already _have_ everything.
 
 Because I'd have to use a state monad or something to chop off the top
 of the list each time I read from it.  This is a FTP client module, so,
 for instance, you might see this session:
 
 cwd h /pub/linuc
 nlst h Nothing
 
 etc.
 
 Each command sends something and reads a reply.  h holds an instance
 of that data structure I posted.
 
 If I just try to read from the list during each command, I would just
 read the same (first) response over and over again.  Or, I'd have to
 store a position (which also requires a state monad), which would lead
 to wasting memory keeping all that stuff around.

Sounds to me like you really want to be putting the code doing this inside
of the IO monad.  It is interacting with the outside world, and maintaining
state at that...

Dave
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Are handles closed automatically when they fall out of scope?

2004-10-24 Thread John Goerzen
On 2004-10-22, Peter Simons [EMAIL PROTECTED] wrote:
 I know it's a rather mundane question, but I couldn't find
 an answer to it!

 So what does happen when I forget to hClose a Handle? Will
 the garbage collector do that for me? Or not?

I'd like the answer to this question, too, but also:

* Does the same hold true for sockets?

* For sockets that also exist as Handles?

* What happens when one Handle corresponding to a socket is closed, but
  another isn't?

* What happens when one gets GC'd but another doesn't?

 And while I am at it: How about Socket? Do I have to sClose
 a socket I obtained from listenOn or accept?

Ah.  I already asked some of this :-)

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Are handles closed automatically when they fall out of scope?

2004-10-22 Thread Peter Simons
I know it's a rather mundane question, but I couldn't find
an answer to it!

So what does happen when I forget to hClose a Handle? Will
the garbage collector do that for me? Or not?

And more specifically, what about the handles
runInteractiveProcess returns? Do I have to close the
stdin Handle? All of them? What happens when I use
terminateProcess? Do I have to hClose them nonetheless?

And while I am at it: How about Socket? Do I have to sClose
a socket I obtained from listenOn or accept?

Any definite answers would be highly appreciated. 

Peter

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users