Re: Process-resume hangs
Gary Byers <[email protected]> Mon, 9 Jan 2006 07:05:17 -0700 (MST)
| Newsgroups | gmane.lisp.openmcl.bugs |
|---|---|
| Message-ID | <[email protected]> |
(ccl:process-suspend ccl:*current-process*) can't work as implemented,
and I'm not sure if -should- work. (If it's decided that it shouldn't,
it should probably detect that case and signal an error rather than
fouling things up as it currently does.)
The documentation claims that a process can suspend itself and be
resumed by another process; it also notes that PROCESS-SUSPEND can
be dangerous, since the suspended process may own a lock or other
resources, and this can (fairly easily) lead to deadlock. It doesn't
note the fact that that act of suspending a process requires a lock,
and if a process suspends itself it continues to own this lock (that
was either not true when the documentation was first written, or
was simply overlooked.)
The functions that you traced (CCL::%SUSPEND-TCR and CCL::%RESUME-TCR)
just call these C functions:
Boolean
lisp_suspend_tcr(TCR *tcr)
{
Boolean suspended;
TCR *current = get_tcr(true);
LOCK(lisp_global(TCR_LOCK),current);
suspended = suspend_tcr(tcr);
UNLOCK(lisp_global(TCR_LOCK),current);
return suspended;
}
Boolean
lisp_resume_tcr(TCR *tcr)
{
Boolean resumed;
TCR *current = get_tcr(true);
LOCK(lisp_global(TCR_LOCK),current);
resumed = resume_tcr(tcr);
UNLOCK(lisp_global(TCR_LOCK), current);
return resumed;
}
So if the current thread suspends itself, it won't UNLOCK the TCR_LOCK
and anything waiting on the TCR_LOCK will wait forever. (That
includes attempts to resume any suspended thread, or invoke the GC, or
a few other things.)
I'm tempted to say that the documentation should be changed and
that PROCESS-SUSPEND should detect attempts to suspend the current
process and refuse to do so. Using a semaphore - as in:
(defvar *a-semaphore* (make-semaphore))
(let* ((proc (process-run-function "example"
#'(lambda ()
(format t "~& suspending test process")
(wait-on-semaphore *a-semaphore*)
(format t "~& resumed ~%")))))
(sleep 5) ; or whatever
(signal-semaphore *a-semaphore*))
- is likely to be more robust for lots of reasons.
On Mon, 9 Jan 2006, Dan Corkill wrote:
> The following simple test hangs in the call to process-resume (running
> on "Version 1.0 (DarwinPPC32)"):
>
> (in-package :common-lisp-user)
>
> (defun simple-test ()
> (let ((process
> (ccl:process-run-function
> "Test"
> #'(lambda ()
> (format t "~&;; Suspending test process...~%")
> (finish-output)
> (ccl:process-suspend ccl:*current-process*)
> (format t "~&;; Resumed~%")
> (finish-output)))))
> (format t "~&;; Starting test...~%")
> ;; Allow plenty of time for test process to start up and suspend:
> (sleep 3)
> (format t "~&;; Resuming test process...~%")
> (finish-output)
> (ccl:process-resume process)
> (format t "~&;; Test completed.~%")))
>
> (progn (trace ccl::%suspend-tcr)
> (trace ccl::%resume-tcr))
>
> (simple-test)
>
>
>
>
>
> _______________________________________________
> Bug-openmcl mailing list
> [email protected]
> http://clozure.com/mailman/listinfo/bug-openmcl
>
>