[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
FYI: 277-gary-rename-remaining-troublesome-ltdl-apis.diff
From: |
Gary V. Vaughan |
Subject: |
FYI: 277-gary-rename-remaining-troublesome-ltdl-apis.diff |
Date: |
Wed, 26 Oct 2005 11:27:35 +0100 (BST) |
User-agent: |
mailnotify/0.7 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Applied to HEAD.
* looking for address@hidden/libtool--devo--1.0--patch-331 to compare with
* comparing to address@hidden/libtool--devo--1.0--patch-331
M NEWS
M doc/libtool.texi
M libltdl/ltdl.c
M libltdl/ltdl.h
M ChangeLog
* modified files
Index: Changelog
from Gary V. Vaughan <address@hidden>
* libltdl/ltdl.h, libltdl/ltdl.c (lt_dlhandle_first): Removed.
* libltdl/ltdl.h, libltdl/ltdl.c (lt_dlhandle_next)
(lt_dlhandle_find, lt_dlforeach): Removed...
(lt_dlhandle_iterate, lt_dlhandle_fetch, lt_dlhandle_map): Similar
functions that are multi-loader safe, and require a registered
interface validator argument.
* doc/libtool.texi: Updated.
* NEWS: Updated.
2005-10-26 Gary V. Vaughan <address@hidden>
--- orig/NEWS
+++ mod/NEWS
@@ -4,11 +4,12 @@
* New tests for support of Automake subdir-objects.
* Fix libltdl on static platforms.
* New LT_CONFIG_LTDL_DIR macro.
-* New lt_dlinterface_register, lt_dlinterface_set_data and
- lt_dlinterface_get_data libltdl API calls to maintain separation of
- concerns between modules loaded by different libraries.
+* New multi-module-loader safe libltdl handle iteration APIs:
+ lt_dlhandle_iterate, lt_dlhandle_fetch, lt_dlhandle_map.
+* New lt_dlinterface_register to maintain separation of concerns between
+ modules loaded by different libraries.
* Removed deprecated APIs from libltdl: lt_dlcaller_register,
- lt_dlcaller_get_data, lt_dlcaller_set_data, lt_dlmutex_register,
+ lt_dlhandle_next, lt_dlhandle_find, lt_dlforeach, lt_dlmutex_register,
lt_dlmutex_lock, lt_dlmutex_unlock, lt_dlmutex_seterror,
lt_dlmutex_geterror, lt_dlmalloc, lt_dlrealloc, lt_dlfree.
* Support for Portland Group compiler on GNU/Linux.
--- orig/doc/libtool.texi
+++ mod/doc/libtool.texi
@@ -3734,35 +3734,86 @@
handles of all the modules you have loaded, these functions allow you to
iterate over libltdl's list of loaded modules:
address@hidden int lt_dlforeach (@w{int (address@hidden) (lt_dlhandle
@var{handle}, void * @var{data})}, @w{void * @var{data}})
-For each loaded module call the function @var{func}. The argument
address@hidden is the handle of one of the loaded modules, @var{data} is
-the @var{data} argument passed to @code{lt_dlforeach}.
-As soon as @var{func} returns a non-zero value for one of the handles,
address@hidden will stop calling @var{func} and immediately return 1.
-Otherwise 0 is returned.
address@hidden {Type} lt_dlinterface_id
+The opaque type used to hold the module interface details for each
+registered libltdl client.
address@hidden deftp
+
address@hidden {Type} int lt_dlhandle_interface (@w{lt_dlhandle
@var{handle},} @w{const char address@hidden)
+Functions of this type are called to check that a handle conforms to a
+library's expected module interface when iterating over the global
+handle list. You should be careful to write a callback function of
+this type that can correctly identify modules that belong to this
+client, both to prevent other clients from accidentally finding your
+loaded modules with the iterator functions below, and vice versa. The
+best way to do this is to check that module @var{handle} conforms
+to the interface specification of your loader using @code{lt_dlsym}.
+
+The callback may be given @strong{every} module loaded by all the
+libltdl module clients in the current address space, including any
+modules loaded by other libraries such as libltdl itself, and should
+return non-zero if that module does not fulfill the interface
+requirements of your loader.
+
address@hidden
+int
+my_interface_cb (lt_dlhandle handle, const char *id_string)
address@hidden
+ char *(*module_id) (void) = NULL;
+
+ /* @r{A valid my_module must provide all of these symbols.} */
+ if (!((module_id = (char*(*)(void)) lt_dlsym ("module_version"))
+ && lt_dlsym ("my_module_entrypoint")))
+ return 1;
+
+ if (strcmp (id_string, module_id()) != 0)
+ return 1;
+
+ return 0;
address@hidden
address@hidden example
address@hidden deftp
+
address@hidden lt_dlinterface_id lt_dlinterface_register (@w{const char
address@hidden, @w{lt_dlhandle_interface address@hidden)
+Use this function to register your interface validator with libltdl,
+and in return obtain a unique key to store and retrieve per-module data.
+You supply an @var{id_string} and @var{iface} so that the resulting
address@hidden can be used to filter the module handles
+returned by the iteration functions below.
address@hidden deftypefun
+
address@hidden int lt_dlhandle_map (@w{lt_dlinterface_id @var{iface}}, @w{int
(address@hidden) (lt_dlhandle @var{handle}, void * @var{data})}, @w{void *
@var{data}})
+For each module that matches @var{iface}, call the function
address@hidden When writing the @var{func} callback function, the
+argument @var{handle} is the handle of a loaded module, and
address@hidden is the last argument passed to @code{lt_dlhandle_map}. As
+soon as @var{func} returns a non-zero value for one of the handles,
address@hidden will stop calling @var{func} and immediately
+return that non-zero value. Otherwise 0 is eventually returned when
address@hidden has been successfully called for all matching modules.
@end deftypefun
address@hidden lt_dlhandle lt_dlhandle_next (@w{lt_dlhandle place})
-Iterate over the loaded module handles, returning the first handle in the
-list if @var{place} is @code{NULL}, and the next one on subsequent calls.
-If @var{place} is the last element in the list of loaded modules, this
-function returns @code{NULL}.
address@hidden lt_dlhandle lt_dlhandle_iterate (@w{lt_dlinterface_id
@var{iface}}, @w{lt_dlhandle @var{place}})
+Iterate over the module handles loaded by @var{iface}, returning the
+first matching handle in the list if @var{place} is @code{NULL}, and
+the next one on subsequent calls. If @var{place} is the last element
+in the list of eligible modules, this function returns @code{NULL}.
@example
lt_dlhandle handle = 0;
+lt_dlinterface_id iface = my_interface_id;
-while ((handle = lt_dlhandle_next (handle)))
+while ((handle = lt_dlhandle_iterate (iface, handle)))
@{
@dots{}
@}
@end example
@end deftypefun
address@hidden lt_dlhandle lt_dlhandle_find (@w{const char address@hidden)
-Search through the loaded module handles for a module named
address@hidden lt_dlhandle lt_dlhandle_fetch (@w{lt_dlinterface_id
@var{iface}}, @w{const char address@hidden)
+Search through the module handles loaded by @var{iface} for a module named
@var{module_name}, returning its handle if found or else @code{NULL}
-if no such named module has been loaded.
+if no such named module has been loaded by @var{iface}.
@end deftypefun
However, you might still need to maintain your own list of loaded
@@ -3770,26 +3821,10 @@
if there were any other data that your application wanted to associate
with each open module. Instead, you can use the following @sc{api}
calls to do that for you. You must first obtain a unique interface id
-from libltdl, and subsequently always use it to retrieve the data you
-stored earlier. This allows different libraries to each store their
-own data against loaded modules, without interfering with one another.
-
address@hidden {Type} lt_dlinterface_id
-The opaque type used to hold individual data set keys.
address@hidden deftp
-
address@hidden {Type} int lt_dlhandle_interface (@w{lt_dlhandle
@var{handle},} @w{const char address@hidden)
-Functions of this type are called to check that a handle conforms to a
-library's expected module interface when iterating over the global
-handle list.
address@hidden deftp
-
address@hidden lt_dlinterface_id lt_dlinterface_register (@w{const char
address@hidden,} @w{lt_dlhandle_interface address@hidden)
-Use this to obtain a unique key to store and retrieve per module data,
-if you supply an @var{id_string} and @var{iface}, then the resulting
address@hidden can be used to filter the module handles
-returned by @samp{lt_dlhandle_next}.
address@hidden deftypefun
+from libltdl as described above, and subsequently always use it to
+retrieve the data you stored earlier. This allows different libraries
+to each store their own data against loaded modules, without
+interfering with one another.
@deftypefun {void *} lt_dlcaller_set_data (@w{lt_dlinterface_id @var{key}},
@w{lt_dlhandle @var{handle}}, @w{void * @var{data}})
Set @var{data} as the set of data uniquely associated with @var{key} and
@@ -3824,76 +3859,6 @@
@var{handle}, or else @code{NULL} if there is none.
@end deftypefun
-The preceding functions can be combined with @code{lt_dlforeach} to
-implement search and apply operations without the need for your
-application to track the modules that have been loaded and unloaded:
-
address@hidden
-int
-my_dlinterface_callback (lt_dlhandle handle, void *key)
address@hidden
- struct my_module_data *my_data;
-
- my_data = lt_dlcaller_get_data (handle, (lt_dlinterface_id) key);
-
- return process (my_data);
address@hidden
-
-int
-my_dlinterface_foreach (lt_dlinterface_id key)
address@hidden
- lt_dlforeach (my_dlinterface_callback, (void *) key);
address@hidden
address@hidden example
-
address@hidden lt_dlhandle lt_dlhandle_first (@w{lt_dlinterface_id @var{key}})
-Normally, you can fetch each of the loaded module handles in turn with
-successive calls to @samp{lt_dlhandle_next} as shown in the example
-above. In that example, the loop iterates over every libltdl loaded
-module in your application, including the modules used by libltdl
-itself! This is useful from within a module loader for example.
-
address@hidden
-Often, your application doesn't want to concern itself with modules
-loaded by the libraries it uses, or for libltdl's internal use. In
-order to do that, you need to specify an interface validator callback:
-
address@hidden
-/* @r{Return non-zero if} @var{handle} @r{doesn't conform to my iface.} */
-int
-iface_validator_callback (lt_dlhandle handle, const char *id_string)
address@hidden
- return (lt_sym (handle, "module_entry_point") != 0)
address@hidden
address@hidden example
-
address@hidden
-When you register for an interface identification key with
address@hidden, you log the interface validator. But
-this time, when you start the iterator loop over the loaded module
-handles, if you fetch the first handle with @samp{lt_dlhandle_first},
-then that and all subsequent calls to @samp{lt_dlhandle_next} will
-skip any loaded module handles that fail the registered interface
-validator callback function:
-
address@hidden
-/* @r{Register for an} interface_id @r{to identify ourselves to} libltdl. */
-interface_id = lt_dlinterface_register ("example", iface_validator_callback);
-
address@hidden
-/* @r{Iterate over the modules related to my} interface_id. */
address@hidden
- lt_dlhandle handle;
- for (handle = lt_dlhandle_first (interface_id);
- handle;
- handle = lt_dlhandle_next (handle))
- @{
- @dots{}
- @}
address@hidden
address@hidden example
address@hidden deftypefun
-
Old versions of libltdl also provided a simpler, but similar, @sc{api}
based around @code{lt_dlcaller_id}. Unfortunately, it had no
provision for detecting whether a module belonged to a particular
--- orig/libltdl/ltdl.c
+++ mod/libltdl/ltdl.c
@@ -2115,92 +2115,69 @@
}
-/* Nasty semantics, necessary for reasonable backwards compatibility:
- Either iterate over the whole handle list starting with
lt_dlhandle_next(0),
- or else iterate over just the handles of modules that satisfy a given
- interface by getting the first element using lt_dlhandle_first(iface). */
-
-static lt__interface_id *iterator = 0;
-
lt_dlhandle
-lt_dlhandle_first (lt_dlinterface_id iface)
-{
- iterator = iface;
-
- return handles;
-}
-
-
-lt_dlhandle
-lt_dlhandle_next (lt_dlhandle place)
+lt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place)
{
lt__handle *handle = (lt__handle *) place;
+ lt__interface_id *iterator = (lt__interface_id *) iface;
+
+ assert (iface); /* iface is a required argument */
if (!handle)
- {
- /* old style iteration across all handles */
- iterator = 0;
- handle = (lt__handle *) handles;
- }
- else
- {
- /* otherwise start at the next handle after the passed one */
- handle = handle->next;
- }
+ handle = (lt__handle *) handles;
- /* advance until the interface check (if we have one) succeeds */
- while (handle && iterator && iterator->iface
+ /* advance while the interface check fails */
+ while (handle && iterator->iface
&& ((*iterator->iface) (handle, iterator->id_string) != 0))
{
handle = handle->next;
}
- if (!handle)
- {
- /* clear the iterator after the last handle */
- iterator = 0;
- }
-
return (lt_dlhandle) handle;
}
lt_dlhandle
-lt_dlhandle_find (const char *module_name)
+lt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name)
{
- lt__handle *cur = (lt__handle *) handles;
+ lt_dlhandle handle = 0;
+
+ assert (iface); /* iface is a required argument */
- if (cur)
+ while ((handle = lt_dlhandle_iterate (handle, iface)))
{
- do
- {
- if (cur->info.name && streq (cur->info.name, module_name))
- break;
- }
- while ((cur = cur->next));
+ lt__handle *cur = (lt__handle *) handle;
+ if (cur && cur->info.name && streq (cur->info.name, module_name))
+ break;
}
- return cur;
+ return handle;
}
+
int
-lt_dlforeach (int (*func) (lt_dlhandle handle, void *data), void *data)
+lt_dlhandle_map (lt_dlinterface_id iface,
+ int (*func) (lt_dlhandle handle, void *data), void *data)
{
- int errors = 0;
- lt__handle *cur;
+ lt__interface_id *iterator = (lt__interface_id *) iface;
+ lt__handle *cur = (lt__handle *) handles;
+
+ assert (iface); /* iface is a required argument */
- cur = (lt__handle *) handles;
while (cur)
{
- lt__handle *tmp = cur;
+ int errorcode = 0;
- cur = cur->next;
- if ((*func) (tmp, data))
+ /* advance while the interface check fails */
+ while (cur && iterator->iface
+ && ((*iterator->iface) (cur, iterator->id_string) != 0))
{
- ++errors;
- break;
+ cur = cur->next;
}
+
+ if ((errorcode = (*func) (cur, data)) != 0)
+ return errorcode;
}
- return errors;
+ return 0;
}
--- orig/libltdl/ltdl.h
+++ mod/libltdl/ltdl.h
@@ -126,10 +126,12 @@
} lt_dlinfo;
LT_SCOPE const lt_dlinfo *lt_dlgetinfo (lt_dlhandle handle);
-LT_SCOPE lt_dlhandle lt_dlhandle_first (lt_dlinterface_id key);
-LT_SCOPE lt_dlhandle lt_dlhandle_next (lt_dlhandle place);
-LT_SCOPE lt_dlhandle lt_dlhandle_find (const char *module_name);
-LT_SCOPE int lt_dlforeach (
+
+LT_SCOPE lt_dlhandle lt_dlhandle_iterate (lt_dlinterface_id iface,
+ lt_dlhandle place);
+LT_SCOPE lt_dlhandle lt_dlhandle_fetch (lt_dlinterface_id iface,
+ const char *module_name);
+LT_SCOPE int lt_dlhandle_map (lt_dlinterface_id iface,
int (*func) (lt_dlhandle handle, void *data),
void *data);
- --
Gary V. Vaughan ())_. address@hidden,gnu.org}
Research Scientist ( '/ http://tkd.kicks-ass.net
GNU Hacker / )= http://www.gnu.org/software/libtool
Technical Author `(_~)_ http://sources.redhat.com/autobook
_________________________________________________________
This patch notification generated by tlaapply version 1.0
http://tkd.kicks-ass.net/arch/address@hidden/cvs-utils--tla--1.0
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (Darwin)
iD8DBQFDX1oWFRMICSmD1gYRAhsFAKCg9/PZVsla018qQLBsiy1HOxhlYQCdGG1j
HmQ7X3KfyAbJA7dMLlLh0Ew=
=t2eV
-----END PGP SIGNATURE-----
- FYI: 277-gary-rename-remaining-troublesome-ltdl-apis.diff,
Gary V. Vaughan <=