I'd been running modlisp in a test environment, and I'd get these
errors, in rare cases:
Error in function UNIX::SIGPIPE-HANDLER: SIGPIPE at #x6E87A2.
[Condition of type SIMPLE-ERROR]
Restarts:
0: [DESTROY] Destroy the process
So I wrote a restart function:
(defun clear-sigpipes (c)
(progn
(format t "~A | (clear-sigpipes) invoked | ~A~%" (date-utils:time-
now-human-readable) c)
(invoke-restart 'destroy)))
And wrapped a (handler-bind) call around the relevant section in the
function where this was occurring:
(defun apache-listen (*apache-stream*)
(let ((*close-apache-stream* t))
(unwind-protect
(handler-bind ((simple-error #'clear-sigpipes))
(loop for *apache-nb-use-socket* from 0
for command = (get-apache-command)
while command do (process-apache-command command)(force-output
*apache-stream*)
until *close-apache-stream*))
(close *apache-stream*))))
This worked.
But then we defined the (apache-listen) function inside a package
definition: (defpackage :modlisp-handler ...) and suddenly, lisp
doesn't know what the 'destroy restart is.
More exactly, lisp thinks 'destroy is part of modlisp-handler and it
looks for it within that package definition; here's an example for
earlier today:
15 Mar 2007 12:23:11 | (clear-sigpipes) invoked |
Error in function UNIX::SIGPIPE-HANDLER: SIGPIPE at #x6E87A2.
Restart MODLISP-HANDLER::DESTROY is not active.
[Condition of type KERNEL:SIMPLE-CONTROL-ERROR]
Restarts:
0: [DESTROY] Destroy the process
So the (handler-bind) did its part correctly and called the (clear-
sigpipes) function as it should have.
But how can (clear-sigpipes) specify that 'destroy does not belong to
the modlisp-handler package?
From: Luís Oliveira
Subject: Re: Resolving Conflicts between (invoke-restart) and (in-package)?
Date:
Message-ID: <m1k5xip7n2.fsf@deadspam.com>
"dpapathanasiou" <···················@gmail.com> writes:
> But how can (clear-sigpipes) specify that 'destroy does not belong to
> the modlisp-handler package?
:destroy, foo:destroy, foo::destroy, etc...
--
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/
From: John Thingstad
Subject: Re: Resolving Conflicts between (invoke-restart) and (in-package)?
Date:
Message-ID: <op.to80bwebpqzri1@pandora.upc.no>
On Thu, 15 Mar 2007 21:35:29 +0100, Lu�s Oliveira
<·············@deadspam.com> wrote:
> "dpapathanasiou" <···················@gmail.com> writes:
>> But how can (clear-sigpipes) specify that 'destroy does not belong to
>> the modlisp-handler package?
>
> :destroy, foo:destroy, foo::destroy, etc...
>
Or write (shadow modlisp:destroy) in the package declaration
perhaps.
--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
> > :destroy, foo:destroy, foo::destroy, etc...
>
> Or write (shadow modlisp:destroy) in the package declaration
> perhaps.
Thanks for suggesting the use of shadow in the definition; I hadn't
thought of that.
I suppose I need to go back and re-read the documentation on packages,
and/or the documentation on the unix package for my lisp (I'm using
CMUCL).
It did occur to me to qualify 'destroy as common-lisp:destroy, but
perhaps I needed the double colon there, or perhaps 'destroy belongs
under the unix package instead.
dpapathanasiou <···················@gmail.com> wrote:
+---------------
| I'd been running modlisp in a test environment,
| and I'd get these errors, in rare cases:
| Error in function UNIX::SIGPIPE-HANDLER: SIGPIPE at #x6E87A2.
+---------------
This happens when a user hits "Stop" or closes a window on the browser
before the page finishes downloading. Get used to it -- it will happen
a *lot* more odten when you go into production with your site.
While the other repliers gave you good advice about avoiding namespace
conflicts, I'm going to suggest something radically different which I
learned from Dan Barlow [thanks, Dan!]:
Instead of trying to *handle* SIGPIPE, simply *ignore* it instead
(set it to SIG_IGN), and handle the much simpler I/O errors you're
going to get when you WRITE (or PRINC or FORMAT) into a closed pipe
or socket. Code for doing this in CMUCL may be found here:
http://groups.google.com/group/comp.lang.lisp/msg/ee284119a99c0d68
-Rob
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
> This happens when a user hits "Stop" or closes a window on the browser
> before the page finishes downloading. Get used to it -- it will happen
> a *lot* more odten when you go into production with your site.
Ah, thanks for clarifying that.. I wasn't sure why they were
occurring.
> Instead of trying to *handle* SIGPIPE, simply *ignore* it instead
> (set it to SIG_IGN), and handle the much simpler I/O errors you're
> going to get when you WRITE (or PRINC or FORMAT) into a closed pipe
> or socket. Code for doing this in CMUCL may be found here:
>
> http://groups.google.com/group/comp.lang.lisp/msg/ee284119a99c0d68
Thanks for mentioning this; I'll definitely study that example and
apply it in our code (fortunately, we're also using CMUCL).
> Instead of trying to *handle* SIGPIPE, simply *ignore* it instead
> (set it to SIG_IGN), and handle the much simpler I/O errors you're
> going to get when you WRITE (or PRINC or FORMAT) into a closed pipe
> or socket. Code for doing this in CMUCL may be found here:
>
> http://groups.google.com/group/comp.lang.lisp/msg/ee284119a99c0d68
Rob,
I got a chance to implement this, but when I recreated the condition,
I got thrown into the debugger, like this:
Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER: the variable UNIX:UNIX-
ERRNO is unbound.
[Condition of type UNBOUND-VARIABLE]
Restarts:
0: [DESTROY] Destroy the process
Debug (type H for help)
(MODLISP-HANDLER::SEND-PROTECTED-OUTPUT #<Function WRITE-STRING
{1004BCC1}> "<html><head> ... </body></html>" #<Stream for descriptor
15>)
Source:
; File: /home/denis/cvs/project01/server/webserver/modlisp-
handler.lisp
(EQL UNIX:UNIX-ERRNO UNIX:EPIPE)
0]
So the (handler-bind) logic did its job correctly, but lisp complains
about the UNIX:UNIX-ERRNO variable in the first (cond) block.
I read the UNIX package chapter in the CMUCL manual, but couldn't find
any references to UNIX:UNIX-ERRNO specifically.
Is this a typo in your example, or am I doing something else wrong?
Inside modlisp-handler.lisp, I've explicitly added :unix to the :use
definition; I've also invoked (defvar *old-sigpipe-handler*
(system:enable-interrupt :sigpipe :ignore)) and it is defined at
runtime (though it is not external to the package, since it's not used
outside modlisp-handler):
* modlisp-handler:*old-sigpipe-handler*
The symbol "*OLD-SIGPIPE-HANDLER*" is not external in the MODLISP-
HANDLER package.
[Condition of type LISP::READER-PACKAGE-ERROR]
Restarts:
0: [CONTINUE] Use symbol anyway.
1: [ABORT ] Return to Top-Level.
Debug (type H for help)
0] 0
#<Function UNIX::SIGPIPE-HANDLER {10300AD9}>
Any suggestions?
A quick update: this problem has been solved.
While gist of the example (http://groups.google.com/group/
comp.lang.lisp/msg/ee284119a99c0d68) is correct (i.e. setting the lisp
process to ignore SIGPIPE is the thing to do), handling the error
under mod_lisp needs to be done differently than what was suggested in
the example code.
Since this is more of a mod_lisp issue than a general lisp language
issue, I've posted the gory details to the mod-lisp-devel mailing list
(http://common-lisp.net/pipermail/mod-lisp-devel/), and it should
appear there shortly, or email me, and I'll send you the snippet with
the explanation.
[Apologies for the slow reply... I was under the weather this
past weekend with the crud that's going around locally...]
dpapathanasiou <···················@gmail.com> wrote:
+---------------
| > Instead of trying to *handle* SIGPIPE, simply *ignore* it instead
| > (set it to SIG_IGN), and handle the much simpler I/O errors you're
| > going to get when you WRITE (or PRINC or FORMAT) into a closed pipe
| > or socket. Code for doing this in CMUCL may be found here:
| >
| > http://groups.google.com/group/comp.lang.lisp/msg/ee284119a99c0d68
|
| Rob,
|
| I got a chance to implement this, but when I recreated the condition,
| I got thrown into the debugger, like this:
|
| Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER: the variable UNIX:UNIX-
| ERRNO is unbound.
| [Condition of type UNBOUND-VARIABLE]
...
| So the (handler-bind) logic did its job correctly, but lisp complains
| about the UNIX:UNIX-ERRNO variable in the first (cond) block.
|
| I read the UNIX package chapter in the CMUCL manual, but couldn't find
| any references to UNIX:UNIX-ERRNO specifically.
|
| Is this a typo in your example, or am I doing something else wrong?
+---------------
Oops! My apologies for not warning you!! I had forgotten about that!!
Yes, way back when the above example URL was posted to the group
[December 2005] it *was* correct code [no typo], but at the time
it was written I was probably using CMUCL-18e, and in that version
and on up through CMUCL-19a, UNIX:UNIX-ERRNO was defined as an
"alien" variable [using CMUCL's internal "alien" FFI mechanism]:
$ src/cmd/cmucl-19a/bin/lisp -quiet -noinit -nositeinit
* (list (lisp-implementation-type) (lisp-implementation-version))
("CMU Common Lisp" "19a-pre3 02-Jul-2004"
cmu> (describe 'unix:unix-errno)
UNIX-ERRNO is an external symbol in the UNIX package.
It is an alien at #x08068454 of type (ALIEN:SIGNED 32).
Its current value is 2.
cmu>
But sometime between CMUCL-19a and CMUCL-19c -- what I'm currently
using and what you're probably using [or later] -- the definition of
UNIX:UNIX-ERRNO changed from an alien variable to a normal function
[probably to handle the underlying changes in "errno" in versions of
Unix/Linux with threads enabled]:
$ src/cmd/cmucl-19c/bin/lisp -quiet -noinit -nositeinit
* (list (lisp-implementation-type) (lisp-implementation-version))
("CMU Common Lisp" "19c Release (19C)")
* (describe 'unix:unix-errno)
UNIX-ERRNO is an external symbol in the UNIX package.
Function: #<Function UNIX:UNIX-ERRNO {1004C851}>
Function arguments:
There are no arguments.
Its defined argument types are:
NIL
Its result type is:
(SIGNED-BYTE 32)
On Wednesday, 11/16/05 05:13:27 pm PST it was compiled from:
target:code/unix.lisp
Created: Monday, 10/10/05 11:46:39 am PDT
Comment: $Header: /project/cmucl/cvsroot/src/code/unix.lisp,v 1.107 2005/10/10 18:46:39 rtoy Exp $
*
As a result of this change, the UNIX:UNIX-ERRNO *variable*
became undefined! :-(
My current code has this horrible conditional in it, which will
break (oops!) if there's ever a CMUCL-20"x" release:
#+(or cmu19a (not cmu19)) unix:unix-errno
#+(and cmu19 (not cmu19a)) (unix:unix-errno)
You could use that [and worry about CMUCL-20"x" later], or if
you *know* you're never going back, just use the function form.
+---------------
| Inside modlisp-handler.lisp, I've explicitly added :unix to the :use
| definition;
+---------------
I don't use "modlisp-handler.lisp" myself [I wrote my own], and I
prefer not to clutter my packages with all the symbols in UNIX, but
it's certainly o.k. to do that if it doesn't cause you any conflicts.
+---------------
| I've also invoked (defvar *old-sigpipe-handler*
| (system:enable-interrupt :sigpipe :ignore)) and it is defined at
| runtime (though it is not external to the package, since it's not
| used outside modlisp-handler):
|
| * modlisp-handler:*old-sigpipe-handler*
|
| The symbol "*OLD-SIGPIPE-HANDLER*" is not external in the MODLISP-
| HANDLER package.
| [Condition of type LISP::READER-PACKAGE-ERROR]
|
| Restarts:
| 0: [CONTINUE] Use symbol anyway.
| 1: [ABORT ] Return to Top-Level.
|
| Debug (type H for help)
| 0] 0
|
| #<Function UNIX::SIGPIPE-HANDLER {10300AD9}>
|
| Any suggestions?
+---------------
You weren't in the MODLISP-HANDLER package when you dropped into
the debugger, and as you said, "it is not external to the package",
so you needed to have typed MODLISP-HANDLER::*OLD-SIGPIPE-HANDLER*
(two colons) instead of MODLISP-HANDLER:*OLD-SIGPIPE-HANDLER*.
It would have worked fine then.
-Rob
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607