Base system

This section describes the base functions for cl-async and also the low-level conditions it uses.


(defun start-event-loop (start-fn &key default-event-cb catch-app-errors))
  => integer

Start the event loop, giving a function that will be run inside the event loop once started. start-event-loop blocks the main thread until the event loop returns, which doesn’t happen until the loop is empty or exit-event-loop is called inside the loop.

This function must be called before any other operations in the library are allowed. If you try to do an async operation without an event loop running, it will throw an error.

;; example:
(start-event-loop (lambda () (format t "Event loop started.~%")))

fatal-cb definition
(lambda (errcode) ...)

logger-cb definition
(lambda (loglevel msg) ...)

loglevel corresponds to syslog levels.

default-event-cb and catch-app-errors

Please see the application error handling section for complete information on these. They correspond 1 to 1 with *default-event-handler* and *catch-application-errors*. Setting them when calling start-event-loop not only cuts down on setfs you have to do when starting your evented app, but also uses thread-local versions of the vars, meaning you can start multiple event loops in multiple threads wiithout using the same values for each thread.


(defmacro with-event-loop ((&key default-event-cb catch-app-errors)
                           &body body)
  => integer

Wraps around start-event-loop, taking away a little bit of the syntax. The options match up 1 to 1 with start-event-loop, so I won’t duplicate the documentation. Because I’m such a great guy though, here’s an example:

(with-event-loop (:catch-app-errors t)


(defun exit-event-loop ())
  => nil

Exit the event loop. This will free up all resources internally and close down the event loop.

Note that this doesn’t let queued events process, and is the equivelent of doing a force close. Unless you really need to do this and return control to lisp, try to let your event loop exit of “natural causes” (ie, no events left to process). You can do this by freeing your signal handlers, servers, etc. This has the added benefit of letting any connected clients finish their requests (without accepting new ones) without completely cutting them off.


(defun add-event-loop-exit-callback (fn))
  => nil

Adds a callback to the event loop that will be fired when it exits. The callback takes no arguments. It can be used to clean up/alert various sections of your code that would benefit from knowing that an event loop has exited (generally you can just put this cleanup directly after calling start-event-loop, but it can make sense to pass in closures that do cleanup for you.


Base event. Signals that “something” happened. Meant to be extended.


extends event-info

Base error event. Signals that “something bad” (an error) happened.


The error code associated with the error event. This is generally retrieved from the underlying OS, but sometimes cl-async will generate its own error conditions, in which case errcode will be -1.


Much like event-errcode, this is generally a system message explaining the error. If it is a cl-async generated error, it will have a string value explaining what happened.