I just encountered the "Asynchronous ID-CHOICE-ERROR" myself tonight, in my case when multiple mcclim applications (in multiple threads) on one screen race to repaint. I don't know if it's related to Nikodemus' test case, which doesn't make any use of threads (excluding the omnipresent CLX event dispatching thread), but at least it's the same error.
Attached is a patch to CLX intending to address a race condition when multiple threads attempt to allocate a resource ID - DISPLAY-RESOURCE-ID-COUNT is incremented, but there is no locking to protect the slot, resulting in intermittent duplicate IDs and subsequent ID-CHOICE-ERROR. I've wrapped the allocation in a with-display, and done the same to the nearby deallocate-resource-id-internal for good measure. This should protect the incf in resourcealloc, the (setf gethash) in save-id, and the remhash in deallocate-resource-id-internal.
--- old-clx/display.lisp 2008-08-21 23:27:35.000000000 -0400 +++ new-clx/display.lisp 2008-08-21 23:27:35.000000000 -0400 @@ -155,11 +155,12 @@
(defmacro allocate-resource-id (display object type) ;; Allocate a resource-id for OBJECT in DISPLAY - (if (member (eval type) +clx-cached-types+) - `(let ((id (funcall (display-xid ,display) ,display))) - (save-id ,display id ,object) - id) - `(funcall (display-xid ,display) ,display))) + `(with-display (,display) + ,(if (member (eval type) +clx-cached-types+) + `(let ((id (funcall (display-xid ,display) ,display))) + (save-id ,display id ,object) + id) + `(funcall (display-xid ,display) ,display))))
(defmacro deallocate-resource-id (display id type) ;; Deallocate a resource-id for OBJECT in DISPLAY @@ -167,7 +168,8 @@ `(deallocate-resource-id-internal ,display ,id)))
(defun deallocate-resource-id-internal (display id) - (remhash id (display-resource-id-map display))) + (with-display (display) + (remhash id (display-resource-id-map display))))
(defun lookup-resource-id (display id) ;; Find the object associated with resource ID