apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Joe Schaefer <joe+gm...@sunstarsys.com>
Subject Re: optional function pointer casts to/from (void *)
Date Thu, 16 Sep 2004 16:35:27 GMT
Joe Orton <jorton@redhat.com> writes:

> On Mon, Sep 13, 2004 at 05:18:40PM -0400, Joe Schaefer wrote:

[...]

> > It should be easy enough to correct this by introducing
> > a private dummy wrapper struct like
> > 
> >   struct apr_dynamic_fn_ptr {
> >     (void)(*function)(void);
> >   }
> 
> You're talking about the pointers stored in the s_phOptionalFunctions
> hash?  It would make sense to do that there, I think, yes please!


Here's a patch (I only tested that it compiles cleanly on linux).
I avoided the dummy wrapper, but the code should amount to the 
same thing, since a pointer to the above struct is just a pointer
to a function pointer.

Index: hooks/apr_hooks.c
===================================================================
RCS file: /home/cvspublic/apr-util/hooks/apr_hooks.c,v
retrieving revision 1.51
diff -u -r1.51 apr_hooks.c
--- hooks/apr_hooks.c   10 May 2004 19:51:03 -0000      1.51
+++ hooks/apr_hooks.c   16 Sep 2004 16:28:36 -0000
@@ -356,26 +356,44 @@

 /* optional function support */

+/* Store (apr_opt_fn_t **) in the hash instead of (apr_opt_fn_t *).
+ * This extra bit of indirection is required on (atypical) platforms
+ * where function pointers like (void(*)(void)) are incompatible with
+ * data pointers like (void *).
+ * Platforms that provide dlsym() usually don't fall into
+ * this category - see the POSIX dlsym() manpage for details.
+ */
+
+
 APU_DECLARE(apr_opt_fn_t *) apr_dynamic_fn_retrieve(const char *szName)
 {
+    apr_opt_fn_t **f;
+
 #ifdef NETWARE
     get_apd
 #endif
     if(!s_phOptionalFunctions)
        return NULL;
-    return (void(*)(void))apr_hash_get(s_phOptionalFunctions,szName,strlen(szName));
+
+    f = apr_hash_get(s_phOptionalFunctions, szName, strlen(szName));
+    return f ? *f : NULL;
 }

 /* Deprecated */
 APU_DECLARE_NONSTD(void) apr_dynamic_fn_register(const char *szName,
                                                   apr_opt_fn_t *pfn)
 {
+    apr_opt_fn_t **f;
+
 #ifdef NETWARE
     get_apd
 #endif
     if(!s_phOptionalFunctions)
        s_phOptionalFunctions=apr_hash_make(apr_hook_global_pool);
-    apr_hash_set(s_phOptionalFunctions,szName,strlen(szName),(void *)pfn);
+
+    f = apr_palloc(apr_hook_global_pool, sizeof *f);
+    *f = pfn;
+    apr_hash_set(s_phOptionalFunctions, szName, strlen(szName), f);
 }

 #if 0

-- 
Joe Schaefer


Mime
View raw message