Callbacks
What's a callback function?
If you are new to asynchronous programming, or have never used callback
functions before, just think of the SLP callback functions as code the
you write but never call directly. Yep, that's
right,
you will probably never call your callback functions directly. Instead,
it will be called by the library when it is ready to report the status
or results of an operation. This allows your program to do other
things while data is being collected by the callback function. Callback
functions are required for all of the major SLP APIs. For more
information,
see SLPReg,
SLPDeReg,
SLPDelAttrs,
SLPFindSrvs,
SLPFindAttrs,
and SLPFindSrvTypes.
Callback functions must accept the parameters that the caller (the
SLP
library) expects to pass to them. This is why callback function
types
are defined. See SLPRegReport,
SLPSrvURLCallback,
SLPAttrCallback.
What's different about SLP callback functions?
Callback functions are an integral part of the SLP API. Developers
usually
associate callbacks with asynchronous APIs, but the SLP API uses
callbacks
for both synchronous and asynchronous operations. Whether the
callback
is called synchronously or asynchronously, depends on the isasync
parameter in the call to SLPOpen.
Remember the following rules and you should not have any problems with
your callback functions.
- Callback functions are called in both synchronous and
asynchronous
cases. The only difference is that in a synchronous case, the
initiating
function
(SLPReg, SLPFindSrvs, etc) will block until all results are
reported
to the callback function.
- The memory passed in to callback functions is owned by the
library. i.e. the callback must strdup strings before
modifiying them
because the memory passed in will either be free'd by the library
when
the callback returns, or is owned by the library, and will be managed
as if it had not been changed by your callback function. In fact, to
this end, pointers to buffers passed to your callback functions are
declared const
in the function signature, making it difficult (but not impossible) for
you to write to these buffers.
- Make your callback
functions as efficient as possible. This is especially important
when a call is made with an async SLPHandle
because results are not collected or collated by the library before the
callback function is called. In other words, in async mode,
the library will call the callback each time a reply message is
received
until the request times out. This means that while the SLP client
library is hanging out inside your callback function, the clock is
ticking on the server.
- If the errcode upon entry to the callback is set to
anything
but SLP_OK,
the rest of the parameters may be invalid. Check the error code
first.
- Use the cookie parameter. It is the best way to get
information
to and from your callback. This parameter allows your application tp
provide context to the callback. When you call an SLP API that accepts
a callback, it also accepts a cookie. Just pass your context with your
function, and the library will pass your context to your callback
function.
How does OpenSLP library handle asynchronous operation?
When an SLP library call is made with an SLPHandle that was opened in
async
mode, the library does everything it can without blocking. It
then
creates a thread (hopefully a user-level thread) and returns
SLP_OK.
The newly created thread processes the request (possibly blocking to
wait
for data to arrive from the network) and calls the callback function as
data is received.
An important thing to remember is that no collection or
collation
of results is performed by the library when a call is initiated in
async
mode. This means that the callback may be called multiple times
with
the same result. This would happen for example if two SAs or DAs
maintained the same registration. It is therefore, up to your
async-aware callback function to perform this collation on behalf of
your application.
Currently all the code is in libslp to allow for asynchronous
operation
except for the calls to pthread_create(). The reason for this is
mainly that no one has really needed asynchronous operation. If
you
feel like you have a good reason to use asynchronous operation then
please
send email to openslp-devel@lists.sourceforge.net.
How does OpenSLP library handle synchronous operation?
When an SLP library call is made with an SLPHandle that was opened in
synchronous
mode, the library will not create a thread. Instead, the calling
thread will perform all processing (which may block) and report results
to the callback function. When in synchronous mode, all of the results
are
collated to ensure no duplicates are returned before any calls are made
to your callback functions. The API function
call
will not return until all results are finished being reported to your
callback function.
Why not just have separate synchronous and asynchronous APIs?
That would have been good choice, but for some reason, the SLP
designers
thought their way would be better. OpenSLP API is just an
implementation
of a standardized specification described in RFC 2614. Furthermore, a
non-callback version may be implemented in terms of the callback
version. This allows programmers to add value without duplicating
effort. If you want such a wrapper library, please feel free to write
one, and add it to the OpenSLP project - that way everyone can benefit!
Can I see some example code?
Yes, example code can be found in the documentation for the SLPReg,
SLPFindSrv,
SLPFindAttrs and SLPFindSrvTypes
functions.