You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by br...@apache.org on 2003/02/04 00:18:27 UTC

cvs commit: apr-iconv/ces _tbl_simple.c

brane       2003/02/03 15:18:27

  Modified:    lib      iconv_module.c iconv.h
               ces      _tbl_simple.c
  Log:
  If libapriconv and the conversion modules are statically linked with
  libapr, they each get their own copy of libapr's functions. In that
  case, it's an extremely bad idea for the apr-iconv code to try to
  unload something that was loaded within the conversion module, because
  the apr_dso_unload cleanups won't get run correctly (due to the
  different cleanup function addresses).
  
  This change addresses this problem by having the conversion module
  unload any dependencies it had loaded previously. Instead of using
  just one event, ICMODEV_DYNDEPS, to load the dependencies, we now use
  two, ICMODEV_DYN_LOAD and ICMODEV_DYN_UNLOAD, one to load and one to
  unload the dependencies.
  
  Without this change, the cleanups for the dependencise loaded by
  _tbl_simple.so would remain in the pool cleanups list until the pool
  was destroyed, by which time the cleanup function addresses were
  invalid (since all modules had been unloaded by then).
  
  Revision  Changes    Path
  1.11      +6 -4      apr-iconv/lib/iconv_module.c
  
  Index: iconv_module.c
  ===================================================================
  RCS file: /home/cvs/apr-iconv/lib/iconv_module.c,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- iconv_module.c	23 Jan 2003 01:04:09 -0000	1.10
  +++ iconv_module.c	3 Feb 2003 23:18:25 -0000	1.11
  @@ -172,7 +172,7 @@
   			depend++;
   		}
   	}
  -	error = ICONV_MOD_DYNDEPS(mod,ctx);
  +	error = ICONV_MOD_DYN_LOAD(mod,ctx);
   	if (error)
   		goto bad;
   	depmod = mod->im_deplist;
  @@ -201,6 +201,7 @@
   		return -1;
   	if (mod->im_flags & ICMODF_LOADED)
   		error = ICONV_MOD_UNLOAD(mod,ctx);
  +	error = ICONV_MOD_DYN_UNLOAD(mod,ctx);
   	deplist = mod->im_deplist;
   	while (deplist) {
   		tmp = deplist->im_next;
  @@ -209,7 +210,7 @@
   	}
   	if (mod->im_handle != NULL)
   		if (apr_dso_unload(mod->im_handle) != APR_SUCCESS)
  -			error = EINVAL;
  +			error = APR_EINVAL;
   	free(mod);
   	return error;
   }
  @@ -220,10 +221,11 @@
   	switch (event) {
   	    case ICMODEV_LOAD:
   	    case ICMODEV_UNLOAD:
  -	    case ICMODEV_DYNDEPS:
  +	    case ICMODEV_DYN_LOAD:
  +	    case ICMODEV_DYN_UNLOAD:
   		break;
   	    default:
  -		return EINVAL;
  +		return APR_EINVAL;
   	}
   	return 0;
   }
  
  
  
  1.15      +8 -2      apr-iconv/lib/iconv.h
  
  Index: iconv.h
  ===================================================================
  RCS file: /home/cvs/apr-iconv/lib/iconv.h,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- iconv.h	23 Jan 2003 01:04:09 -0000	1.14
  +++ iconv.h	3 Feb 2003 23:18:26 -0000	1.15
  @@ -66,7 +66,8 @@
    */
   #define	ICMODEV_LOAD	1	/* module load. after dependencies resolved */
   #define	ICMODEV_UNLOAD	2	/* module unload */
  -#define	ICMODEV_DYNDEPS	3	/* load dynamic dependencies */
  +#define ICMODEV_DYN_LOAD    3   /* load dynamic dependencies */
  +#define ICMODEV_DYN_UNLOAD  4   /* unload dynamic dependencies */
   
   struct iconv_module_depend {
   	int		md_type;
  @@ -103,11 +104,16 @@
   	void *		im_data;
   	const void *	im_depdata;	/* data if module loaded from dependency */
   	const void *	im_args;
  +
  +        /* This is module-private data. Nothing outside the module
  +           itself may touch it. */
  +        void *im_private;
   };
   
   #define	ICONV_MOD_LOAD(mod,ctx)	(mod)->im_desc->imd_event(mod, ICMODEV_LOAD,ctx)
   #define	ICONV_MOD_UNLOAD(mod,ctx)	(mod)->im_desc->imd_event(mod, ICMODEV_UNLOAD,ctx)
  -#define	ICONV_MOD_DYNDEPS(mod,ctx)	(mod)->im_desc->imd_event(mod, ICMODEV_DYNDEPS,ctx)
  +#define	ICONV_MOD_DYN_LOAD(mod,ctx)	(mod)->im_desc->imd_event(mod, ICMODEV_DYN_LOAD,ctx)
  +#define	ICONV_MOD_DYN_UNLOAD(mod,ctx)	(mod)->im_desc->imd_event(mod, ICMODEV_DYN_UNLOAD,ctx)
   
   /*
    * iconv converter definitions.
  
  
  
  1.9       +18 -4     apr-iconv/ces/_tbl_simple.c
  
  Index: _tbl_simple.c
  ===================================================================
  RCS file: /home/cvs/apr-iconv/ces/_tbl_simple.c,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- _tbl_simple.c	9 Jan 2003 22:54:56 -0000	1.8
  +++ _tbl_simple.c	3 Feb 2003 23:18:26 -0000	1.9
  @@ -38,7 +38,8 @@
   static int
   table_open(struct iconv_ces *ces, apr_pool_t *ctx)
   {
  -	ces->data = (void *)(ces->mod->im_deplist->im_desc->imd_data);
  +        struct iconv_module *ccsmod = ces->mod->im_private;
  +        ces->data = (void *)(ccsmod->im_desc->imd_data);
   	return 0;
   }
   
  @@ -129,23 +130,36 @@
   
   	if (mod->im_args == NULL)
   		return APR_EINVAL;
  +        if (mod->im_private != NULL)
  +            return APR_EINVAL;
   	error = apr_iconv_mod_load(mod->im_args, ICMOD_UC_CCS, NULL, &ccsmod, ctx);
   	if (error)
   		return error;
  -	ccsmod->im_next = mod->im_deplist;
  -	mod->im_deplist = ccsmod;
  +        mod->im_private = ccsmod;
   	return APR_SUCCESS;
   }
   
   static apr_status_t
  +table_unload_ccs(struct iconv_module *mod, apr_pool_t *ctx)
  +{
  +    struct iconv_module *ccsmod = mod->im_private;
  +    if (ccsmod == NULL)
  +        return APR_EINVAL;
  +    mod->im_private = NULL;
  +    return apr_iconv_mod_unload(ccsmod, ctx);
  +}
  +
  +static apr_status_t
   table_event(struct iconv_module *mod, int event, apr_pool_t *ctx)
   {
   	switch (event) {
   	    case ICMODEV_LOAD:
   	    case ICMODEV_UNLOAD:
   		break;
  -	    case ICMODEV_DYNDEPS:
  +            case ICMODEV_DYN_LOAD:
   		return table_load_ccs(mod,ctx);
  +            case ICMODEV_DYN_UNLOAD:
  +                return table_unload_ccs(mod,ctx);
   	    default:
   		return APR_EINVAL;
   	}