Indeed, both are useful and can be implemented independently.
The system/library APIs I'm calling into are all async so I suppose that approach is the easiest. However, that places the burden on the Pike application to wait long enough (maybe a second or two) to find services.
Another thing is unclear to me: the library functions take a void *context value and I'd stuff the browser object in there. But how can I be sure the context pointer I get handed in the callback is the same object I had initially (or even a valid object)? In this case I believe I'm able to cancel an ongoing lookup task from the object's exit callback so I'm probably safe anyway.