[mcclim-devel] [bug] Asynchronous ID-CHOICE-ERROR -- CLX or McCLIM?

Andy Hefner ahefner at gmail.com
Fri Aug 22 17:40:55 UTC 2008


I think there are two bugs at play here - first, that CLX makes no
attempt to avoid reusing IDs that are still in use once the count
wraps around, and second that in this instance mcclim creates millions
of gcontexts without freeing them.

I've hacked resourcealloc in CLX to check against the id cache,
skipping IDs which are still in use, but this runs into the problem
that not all types (in particular, graphics contexts) are stored in
the cache. There's some comment about this not being useful and
wasting space in depdefs.lisp next to defconstant +clx-cached-types+,
and without considering the performance implications I've worked
around it by setting the hash table entry to T at the point the ID is
allocated, so that (I hope) every allocated resource is now there. To
do this correctly also requirse that the deallocate-resource-id be
changed to unconditionally invoke deallocate-resource-id-internal
(thereby making the macro useless), which I've neglected to do. With
that in mind, here's a version of resourcealloc with the changes
described:

(defun resourcealloc (display)
  ;; Allocate a resource-id for in DISPLAY
  (declare (type display display))
  (declare (clx-values resource-id))

  (loop for next-count upfrom (1+ (display-resource-id-count display))
        repeat (1+ (display-resource-id-mask display))
        as id = (dpb next-count
                     (display-resource-id-byte display)
                     (display-resource-id-base display))
        do
        (when (nth-value 1 (gethash id (display-resource-id-map display)))
          #+NIL
          (format *trace-output* "~&Skipping ~X (~A)~%" id (gethash id
(display-resource-id-map display))))
        (when (zerop (random 10000)) (format *trace-output* "~&~X~%" id))
        (unless (nth-value 1 (gethash id (display-resource-id-map display)))
          (setf (display-resource-id-count display) next-count)
          #+NIL
          (format *trace-output* "~&Allocating ~X (~A IDs in use)~%"
                  id
                  (hash-table-count (display-resource-id-map display)))
          (setf (gethash id (display-resource-id-map display)) t)
          (when (= id #x2A00027) (break "Hi there."))
          (return-from resourcealloc id)))
  (assert (= (hash-table-count (display-resource-id-map display))
             (1+ (display-resource-id-mask display))))
  (error "Available X resource IDs have been exhausted."))

Fixing this allocation issue doesn't solve the underlying problem that
this test causes mcclim to exhaust the available space of resource-ids
by never freeing these gcontexts.



More information about the mcclim-devel mailing list