libevent for Lisp: A Signal Example
- CMUCL/SBCL's SERVE-EVENT
- cl-event (libevent for Lisp, using cffi; three years old)
- cl-async (also using cffi libevent wrapper, actively developed)
I was ready to dive in and get things current, when one last Google search turned up cl-async. This little bugger was hard to find, as at that point it had not been listed on CLiki. (But it is now :-)). Andrew Lyon has done a tremendous amount of work on cl-async, with a very complete set of bindings for libevent. This is just what I had been looking for, so I jumped in immediately.
As one might imagine from the topic of this post, there's a lot to be explored, uncovered, and developed further around async programming in Lisp. I'll start off slowly with a small example, and add more over the course of time.
I also hope to cover IOlib and SBCL's SERVE-EVENT in some future posts. Time will tell... For now, let's get started with cl-async in SBCL :-)
In a previous post, I discussed getting an environment set up with SBCL, I the rest of this post assumes that has been read and done :-)
Getting cl-async and Setting Up an SBCL Environment for Hacking
Now let's download cl-async and install the Libevent bindings :-)
With the Lisp Libevent bindings installed, we're now ready to create a Lisp image to assist us when exploring cl-async. A Lisp image saves the current state of the REPL, with all the loaded libaries, etc., allowing for rapid start-ups and script executions. Just the thing, when you're iterating on something :-)
Example: Adding a Signal Handler
Let's dive into some signal handling now! Here is some code I put together as part of an effort to beef up the examples in cl-async:
Note that the as: is a nickname for the package namespace cl-async: .
As one might expect, there is a function to start the event loop. However, what is a little different is that one doesn't initialize the event loop directly, but with a callback. As such, one cannot set up handlers, etc., except within the scope of this callback.
We've got the setup-handler function for that, which adds a callback for a SIGINT event. Let's try it out :-)
Once your script has finished loading the core, you should see output like the above, with no return to the shell prompt.
When we send a SIGINT with ^C , we can watch our callback get fired:
Next up, we'll take a look at other types of handlers in cl-async.