From: Patrick May
Subject: Is unwind-protect required here?
Date: 
Message-ID: <m2ab7xas3j.fsf@spe.com>
     I was looking at some networking code I've been working on and had
a question about my use of unwind-protect.  Boiled down to the smallest
example, consider this handler function:

(defun echo-handler (socket)
  "A socket handler that replies to messages with an echo."
  (unwind-protect
       (do ((message (read-line socket nil) (read-line socket nil)))
           ((null message))
         (write-line message socket)
         (force-output socket))
    (close socket :abort t)))

Is the unwind-protect necessary here?  I don't think it is, but is it
better style than something like this:

(defun echo-handler (socket)
  "A socket handler that replies to messages with an echo."
  (do ((message (read-line socket nil) (read-line socket nil)))
      ((null message) (close socket :abort t))
    (write-line message socket)
    (force-output socket)))

Thanks,

Patrick

------------------------------------------------------------------------
S P Engineering, Inc.  | Large scale, mission-critical, distributed OO
                       | systems design and implementation.
http://www.spe.com/pjm | (C++, Java, Common Lisp, Jini, middleware, SOA)

From: Joshua Taylor
Subject: Re: Is unwind-protect required here?
Date: 
Message-ID: <45840891-014d-4847-90b3-497e9f6c040c@h20g2000yqn.googlegroups.com>
On Mar 7, 5:25 pm, Patrick May <····@spe.com> wrote:
>      I was looking at some networking code I've been working on and had
> a question about my use of unwind-protect.  Boiled down to the smallest
> example, consider this handler function:
>
> (defun echo-handler (socket)
>   "A socket handler that replies to messages with an echo."
>   (unwind-protect
>        (do ((message (read-line socket nil) (read-line socket nil)))
>            ((null message))
>          (write-line message socket)
>          (force-output socket))
>     (close socket :abort t)))
>
> Is the unwind-protect necessary here?  I don't think it is, but is it
> better style than something like this:
>
> (defun echo-handler (socket)
>   "A socket handler that replies to messages with an echo."
>   (do ((message (read-line socket nil) (read-line socket nil)))
>       ((null message) (close socket :abort t))
>     (write-line message socket)
>     (force-output socket)))
>
> Thanks,
>
> Patrick

Why is echo-handler closing a stream that it didn't open?

If in the real code, echo-handler /is/ opening a socket, then you
could abstract away with a macro, e.g., WITH-OPEN-SOCKET, which would
probably expand into an UNWIND-PROTECT (just like WITH-OPEN-FILE does
in some (many? most?) implementations).

//JT
From: Patrick May
Subject: Re: Is unwind-protect required here?
Date: 
Message-ID: <m21vt8c0k8.fsf@spe.com>
Joshua Taylor <···········@gmail.com> writes:
> On Mar 7, 5:25 pm, Patrick May <····@spe.com> wrote:
>>      I was looking at some networking code I've been working on and had
>> a question about my use of unwind-protect.  Boiled down to the smallest
>> example, consider this handler function:
>>
>> (defun echo-handler (socket)
>>   "A socket handler that replies to messages with an echo."
>>   (unwind-protect
>>        (do ((message (read-line socket nil) (read-line socket nil)))
>>            ((null message))
>>          (write-line message socket)
>>          (force-output socket))
>>     (close socket :abort t)))
>>
>> Is the unwind-protect necessary here?  I don't think it is, but is it
>> better style than something like this:
>>
>> (defun echo-handler (socket)
>>   "A socket handler that replies to messages with an echo."
>>   (do ((message (read-line socket nil) (read-line socket nil)))
>>       ((null message) (close socket :abort t))
>>     (write-line message socket)
>>     (force-output socket)))
>
> Why is echo-handler closing a stream that it didn't open?

     In the full code the handler gets spawned by process-run-function,
so the handler ends up owning the socket.

> If in the real code, echo-handler /is/ opening a socket, then you
> could abstract away with a macro, e.g., WITH-OPEN-SOCKET, which would
> probably expand into an UNWIND-PROTECT (just like WITH-OPEN-FILE does
> in some (many? most?) implementations).

     I can (and do) use with-open-socket in the server, but each
connection is handled by a thread from a pool (I know the constraints
well enough that I don't need to use POSIX select in this situation).

Thanks,

Patrick

------------------------------------------------------------------------
S P Engineering, Inc.  | Large scale, mission-critical, distributed OO
                       | systems design and implementation.
http://www.spe.com/pjm | (C++, Java, Common Lisp, Jini, middleware, SOA)
From: D Herring
Subject: Re: Is unwind-protect required here?
Date: 
Message-ID: <49b2fb1c$0$3339$6e1ede2f@read.cnntp.org>
Patrick May wrote:
> (defun echo-handler (socket)
>   "A socket handler that replies to messages with an echo."
>   (unwind-protect
>        (do ((message (read-line socket nil) (read-line socket nil)))
>            ((null message))
>          (write-line message socket)
>          (force-output socket))
>     (close socket :abort t)))

In this version, the socket will be closed no matter what happens in DO.


> (defun echo-handler (socket)
>   "A socket handler that replies to messages with an echo."
>   (do ((message (read-line socket nil) (read-line socket nil)))
>       ((null message) (close socket :abort t))
>     (write-line message socket)
>     (force-output socket)))

In this version, the socket will not be closed if anything in DO does 
a nonlocal exit (e.g. signals a condition).


Wheter the socket needs to be closed is up to you.  Very little 
performance is lots by UNWIND-PROTECT.

- Daniel
From: Patrick May
Subject: Re: Is unwind-protect required here?
Date: 
Message-ID: <m263ikc0rf.fsf@spe.com>
D Herring <········@at.tentpost.dot.com> writes:
> Patrick May wrote:
>> (defun echo-handler (socket)
>>   "A socket handler that replies to messages with an echo."
>>   (unwind-protect
>>        (do ((message (read-line socket nil) (read-line socket nil)))
>>            ((null message))
>>          (write-line message socket)
>>          (force-output socket))
>>     (close socket :abort t)))
>
> In this version, the socket will be closed no matter what happens in DO.

     Yup.

>> (defun echo-handler (socket)
>>   "A socket handler that replies to messages with an echo."
>>   (do ((message (read-line socket nil) (read-line socket nil)))
>>       ((null message) (close socket :abort t))
>>     (write-line message socket)
>>     (force-output socket)))
>
> In this version, the socket will not be closed if anything in DO does
> a nonlocal exit (e.g. signals a condition).

     My very poorly phrased question was whether or not that could
actually happen in this case.

> Wheter the socket needs to be closed is up to you.  Very little
> performance is lots by UNWIND-PROTECT.

     Thanks, I think I'll leave it there, then.

Regards,

Patrick

------------------------------------------------------------------------
S P Engineering, Inc.  | Large scale, mission-critical, distributed OO
                       | systems design and implementation.
http://www.spe.com/pjm | (C++, Java, Common Lisp, Jini, middleware, SOA)