Lisp HUG Maillist Archive

Delivered app (Mac) w/ defparameter hangs app

Note: the problem below is specific to Mac (I can't test delivery on Windows).

It's taken me 3 days to find a workaround to this particular problem. I'm posting this here instead of to support in hopes that I don't understand something in Common Lisp and will learn. If no one has an answer for me I'll pass it along to support...

In my app, my main interface held the app preferences that were loaded on startup. You could think of it like this:

(define-interface app ()
  ((prefs :accessor app-prefs))
  (:default-initargs
   :create-callback 'create-app))

(defmethod create-app ((interface app))
  (setf (app-prefs interface) (read-preferences-file)))

And this works great. However, as the app grew, I wanted to break out the code and make the preferences global (maybe in the future I would have multiple app interfaces open at once?).

So, I removed the create-app callback that read the preferences file and changed my "main" function to do the following:

(defvar *prefs* nil)

(defun launch ()
  (setq *prefs* (read-preferences-file))
  (display (make-instance 'app)))

When I do this, though, while it works in the IDE it completely hangs the delivered app. I can launch it, and whatever interface I set to display initially (even a display-message) will show up, but the interface is completely unresponsive and I need to force quit the application.

The *only* way I've worked around this is to put the (setq *prefs* ...) inside the cocoa-event-loop process. And there is nothing in read-preferences-file that requires the cocoa-event-loop.

At first I thought maybe this was a special variable issue; perhaps *prefs* was thread-local and perhaps the cocoa-event-loop was created before *prefs*? But if I make display-message show a value from *prefs* it is correct. So that's not it?

Anyway, here's what I would hope:

* If this is me being stupid, can someone explain to me why this is bad and what's happening under-the-hood?

* This took me several days to figure out going commit-by-commit until I figured out what change caused the issue. Is there a way to debug an unresponsive, delivered app (a key press to break into the REPL)?

Thanks for any info!

Jeff M.

Re: Delivered app (Mac) w/ defparameter hangs app

Maybe it's a bad idea to set slots in the interface from the create-callback? If so, it may be possible to initialize the preferences earlier, and pass them to the make-instance or some specialized constructor.

Have you looked at #'lw:user-preference (and its associated setf form)? I discovered this by chance some time back, and it works quite well for the (simple!) GUI applications that I've written.

For debugging: you should be able to do this :interrupt-function argument to #'deliver; you may find it useful to suspend threads as the first thing in your interrupt-function. Once you have this in place, you should be able to use Ctrl-C to brea into your application.

On 13 Feb 2014, at 17:57 , Jeffrey Massung <massung@gmail.com> wrote:

Note: the problem below is specific to Mac (I can't test delivery on Windows).

It's taken me 3 days to find a workaround to this particular problem. I'm posting this here instead of to support in hopes that I don't understand something in Common Lisp and will learn. If no one has an answer for me I'll pass it along to support...

In my app, my main interface held the app preferences that were loaded on startup. You could think of it like this:

(define-interface app ()
  ((prefs :accessor app-prefs))
  (:default-initargs
   :create-callback 'create-app))

(defmethod create-app ((interface app))
  (setf (app-prefs interface) (read-preferences-file)))

And this works great. However, as the app grew, I wanted to break out the code and make the preferences global (maybe in the future I would have multiple app interfaces open at once?).

So, I removed the create-app callback that read the preferences file and changed my "main" function to do the following:

(defvar *prefs* nil)

(defun launch ()
  (setq *prefs* (read-preferences-file))
  (display (make-instance 'app)))

When I do this, though, while it works in the IDE it completely hangs the delivered app. I can launch it, and whatever interface I set to display initially (even a display-message) will show up, but the interface is completely unresponsive and I need to force quit the application.

The *only* way I've worked around this is to put the (setq *prefs* ...) inside the cocoa-event-loop process. And there is nothing in read-preferences-file that requires the cocoa-event-loop.

At first I thought maybe this was a special variable issue; perhaps *prefs* was thread-local and perhaps the cocoa-event-loop was created before *prefs*? But if I make display-message show a value from *prefs* it is correct. So that's not it?

Anyway, here's what I would hope:

* If this is me being stupid, can someone explain to me why this is bad and what's happening under-the-hood?

* This took me several days to figure out going commit-by-commit until I figured out what change caused the issue. Is there a way to debug an unresponsive, delivered app (a key press to break into the REPL)?

Thanks for any info!

Jeff M.

Re: Delivered app (Mac) w/ defparameter hangs app

Unable to parse email body. Email id is 12875

Updated at: 2020-12-10 08:34 UTC