At 2:03 PM -0700 1999/05/22, Jeff Ishaq wrote:
>If I SysLibLoad() my shared library twice, I get two
>sequential valid reference numbers. In addition, both copies
>of the library have their Sleep and Wake entry points called
>upon sleeping and waking. This implies that each instance of
>the library has its own uniqute SysLibTblEntryPtr (this is
>implicit in the fact that they each have their own reference
>number, really).
At 7:16 AM -0700 1999/05/24, Greg Winton wrote:
>Great detective work! These are really interesting results. I guess I
>didn't check this our thoroughly enough. I agree with your (other) post
>that this is probably an OS bug. Perhaps Palm will confirm?
Nope, it's a feature. :o)
SysLibFind is ALWAYS called first to obtain the loaded library reference number,
deferring to a SysLibLoad only when SysLibFind returns sysErrLibNotFound. In the
latter case, when your code becomes responsible for loading the library, it also
becomes responsible for unloading it. Generally speaking then, only one instance
(client context) of a shared library will ever be loaded at one time.
That said, multiple client contexts of the same shared library are possible however,
as you have discovered by simply loading the library multiple times. There are
side-effects of this which must be kept in mind as you code the library's required
entrypoints... specifically Sleep and Wake.
Every time a shared library is loaded, a new client context is created. The client
context includes the globalsP field of the SysLibTblEntry structure passed to the
install routine for initialization. Normally, the install routine just allocates a
pointer and assigns it to globalsP, thus no two client contexts "know" about each
other's globalsP field. This is fairly analogous to shared library implementations on
other platforms.
When the Palm OS sleeps and wakes, it iterates over all loaded shared library client
contexts, calling their sleep and wake entrypoints. If a library has more than one
client context active, its sleep and wake entries WILL be called multiple times. It is
important to keep this fact in mind when coding the sleep and wake implementations.
Also important to keep in mind is the fact that the sleep and wake entrypoints may be
called from within an interrupt service routine, so ISR coding rules apply.
Sometimes multiple client contexts need access to global data common to the library in
addition to the global data of the client context. In this case, the feature manager
can be used during the library's installation to register a second pointer allocation
containing the library-common global data, with a field of the client context globals
structure set to point to this allocation. Of course, the install routine must first
ask the feature manager for this library-common global data pointer and only allocate
a new one if one does not exist (i.e. if this is the very first load of the library).
Using the feature manager in this way is similar to sharing data between multiple
applications, or between an application and a shared library, or... whatever.
If the library is intended to support multiple client contexts, the sleep and wake
entrypoints may need to avoid duplicate processing since they'll be called once for
each loaded client context. This is where the library-common globals are needed.
Simply set up a sleep/wake counter (i.e. your own counting semaphore) and activate
your sleep and wake logic when the counter equals one, for example.
Hope that explanation helps!
Regards,
Jim Schram
3Com/Palm Computing
Partner Engineering