Hi all,
I'm experimenting with hunchentoot with a view to porting my web app. I have 0.4.11 running on SBCL-1.0 and Ubuntu Linux.
I have a default handler set up, and call: (hunchentoot:start-server :port 8888)
and it works fine.
However, when I call the above function from inside the startup sequence of the asdf system that loads the app, it hangs.
What am I doing wrong here?
Jonathon McKitrick -- My other computer is your Windows box.
On Mon, 18 Dec 2006 17:14:59 +0000, Jonathon McKitrick jcm@FreeBSD-uk.eu.org wrote:
I'm experimenting with hunchentoot with a view to porting my web app. I have 0.4.11 running on SBCL-1.0 and Ubuntu Linux.
I have a default handler set up, and call: (hunchentoot:start-server :port 8888)
and it works fine.
However, when I call the above function from inside the startup sequence of the asdf system that loads the app, it hangs.
What am I doing wrong here?
You should send real code so we can see what you're doing. FWIW, I don't know what you mean with "from inside the startup sequence."
My other computer is your Windows box.
I doubt that...
Cheers, Edi.
On Mon, Dec 18, 2006 at 06:35:48PM +0100, Edi Weitz wrote: : On Mon, 18 Dec 2006 17:14:59 +0000, Jonathon McKitrick jcm@FreeBSD-uk.eu.org wrote: : : > I'm experimenting with hunchentoot with a view to porting my web : > app. I have 0.4.11 running on SBCL-1.0 and Ubuntu Linux. : > : > I have a default handler set up, and call: : > (hunchentoot:start-server :port 8888) : > : > and it works fine. : > : > However, when I call the above function from inside the startup : > sequence of the asdf system that loads the app, it hangs. : > : > What am I doing wrong here? : : You should send real code so we can see what you're doing. FWIW, I : don't know what you mean with "from inside the startup sequence."
Well, it's difficult to simulate, but I'll try. The last file loaded by asdf does this:
(defun rlg-start () "Entry point after loading via asdf/require." (db:connect-to-rlg) (ajax:rlg-web-start :port 9000))
(rlg-start)
------------------------
And another file has this:
(in-package :ajax)
(defparameter *rlg-server* nil)
(defun rlg-web-start (&key port) "Start the server, initialize dispatch table." (setf *dispatch-table* (list (create-static-file-dispatcher-and-handler "/index.html" #P "web/ah01/") 'default-dispatcher)) (format t "; --> Starting...~%") (setf *rlg-server* (hunchentoot:start-server :port 4242)) (format t "; --> Ready!~%"))
Jonathon McKitrick -- My other computer is your Windows box.
On Mon, 18 Dec 2006 18:03:19 +0000, Jonathon McKitrick jcm@FreeBSD-uk.eu.org wrote:
(ajax:rlg-web-start :port 9000))
[...]
(setf *rlg-server* (hunchentoot:start-server :port 4242))
You're sure the above is not the culprit?
Other than that, what you sent is not a self-contained test case. Send something that I can just use with instructions how to reproduce the faulty behaviour.
Cheers, Edi.
On Mon, Dec 18, 2006 at 08:27:29PM +0100, Edi Weitz wrote: : On Mon, 18 Dec 2006 18:03:19 +0000, Jonathon McKitrick jcm@FreeBSD-uk.eu.org wrote: : : > (ajax:rlg-web-start :port 9000)) : > : > [...] : > : > (setf *rlg-server* (hunchentoot:start-server :port 4242)) : : You're sure the above is not the culprit? : : Other than that, what you sent is not a self-contained test case. : Send something that I can just use with instructions how to reproduce : the faulty behaviour.
Okay, I'm attaching 2 small files. If you start sbcl, load hunchentoot, then load hunchentoot-start.lisp, the server will start and all is well.
If you start sbcl, then load test-hunchentoot.asd, the system will hang at the start-server call.
Jonathon McKitrick -- My other computer is your Windows box.
On Mon, 18 Dec 2006 20:12:45 +0000, Jonathon McKitrick jcm@FreeBSD-uk.eu.org wrote:
Okay, I'm attaching 2 small files. If you start sbcl, load hunchentoot, then load hunchentoot-start.lisp, the server will start and all is well.
If you start sbcl, then load test-hunchentoot.asd, the system will hang at the start-server call.
Yes, I can reproduce it now, thanks. Actually, you don't even need ASDF - just COMPILE-FILE hunchentoot-start.lisp and LOAD the resulting FASL file, and SBCL hangs.
This doesn't happen with LispWorks, though. At the moment, I have no idea what the problem is. Maybe an SBCL expert is reading this and can help.
Cheers, Edi.
On Mon, Dec 18, 2006 at 09:32:52PM +0100, Edi Weitz wrote:
This doesn't happen with LispWorks, though. At the moment, I have no idea what the problem is. Maybe an SBCL expert is reading this and can help.
Definitely an SBCL bug. Paring it down, it's hanging at the call to make-instance -- it looks like any make-instance will do, it's not something socket-specific. That is, this is a minimal testcase which shows the problem is:
(defclass foo () ()) (defun foo (&aux done) (flet ((do-it () (make-instance 'foo) (setf done t))) (sb-thread:make-thread #'do-it) (loop until done do (sleep 0.1)))) (foo)
Remove the make-instance, and it terminates. Move the make-instance into the main thread, and it terminates. Leave it there, it hangs (and never gets to the point of running things like shared-initialize or lsof would report the socket is created).
CC'd sbcl-devel, since getting into CLOS+thread bugs is way beyond my level of SBCL knowledge. I hope that's an open list, as I'm not subscribed there with this address. For those on that list but not tbnl-devel: compile-file + load'ing the above snippet hangs SBCL.
From sbcl-devel: Loading a FASL file takes the big compiler lock. The first call to MAKE-INSTANCE in compiled code with constant class-name and initargs compiles an optimized constructor (a "ctor"). The end.
So I guess the answer is "don't do that then", at least for now. Putting your startup call in a :after method on asdf:perform doesn't seem to work either, but deferring the startup into a thread of its own (i.e., instead of a toplevel (startup) do (make-thread 'startup)) lets the locks all get released.
On Mon, Dec 18, 2006 at 03:24:09PM -0700, Robert J. Macomber wrote: : seem to work either, but deferring the startup into a thread of its
Thank you all for your help. Whether the bug (if it is, in fact, a bug) gets fixed or not, I can solve the problem.
Jonathon McKitrick -- My other computer is your Windows box.
On Mon, 18 Dec 2006 15:24:09 -0700, "Robert J. Macomber" tbnl@rojoma.com wrote:
So I guess the answer is "don't do that then", at least for now. Putting your startup call in a :after method on asdf:perform doesn't seem to work either, but deferring the startup into a thread of its own (i.e., instead of a toplevel (startup) do (make-thread 'startup)) lets the locks all get released.
Ah, OK. Thanks for the detective work. By coincidence I came across a similar case last Friday. Another, SBCL-specific, workaround is to add a file precompile.lisp to your ASDF system definition that is guaranteed to be the very last file to be compiled and loaded (and that is also guaranteed to be re-compiled whenever something changes in the rest of the system). This file should contain only one form:
(sb-pcl::precompile-random-code-segments)
I don't think this is documented or officially endorsed by the SBCL developers, but it should pre-compile optimized constructors and other CLOS functions.
I'm baffled. I'm running SBCL 1.0 on a Gentoo system and it works perfectly for me. I cannot make your test case hang.
-jeff