1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include "apu_config.h"
23 #include "apr_pools.h"
24 #include "apr_tables.h"
26 #include "apr_strings.h"
28 #include "apr_file_io.h"
31 #include "apu_internal.h"
32 #include "apu_version.h"
36 static apr_thread_mutex_t
* mutex
= NULL
;
38 static apr_hash_t
*dsos
= NULL
;
41 #if APR_HAS_THREADS && APU_DSO_BUILD
42 apr_status_t
apu_dso_mutex_lock()
44 return apr_thread_mutex_lock(mutex
);
46 apr_status_t
apu_dso_mutex_unlock()
48 return apr_thread_mutex_unlock(mutex
);
51 apr_status_t
apu_dso_mutex_lock() {
54 apr_status_t
apu_dso_mutex_unlock() {
59 #define CLEANUP_CAST (apr_status_t (*)(void*))
62 static apr_status_t
apu_dso_term(void *ptr
)
64 /* set statics to NULL so init can work again */
70 /* Everything else we need is handled by cleanups registered
71 * when we created mutexes and loaded DSOs
76 apr_status_t
apu_dso_init(apr_pool_t
*pool
)
78 apr_status_t ret
= APR_SUCCESS
;
87 /* Top level pool scope, need process-scope lifetime */
88 for (parent
= global
= pool
; parent
; parent
= apr_pool_parent_get(global
))
91 dsos
= apr_hash_make(global
);
94 ret
= apr_thread_mutex_create(&mutex
, APR_THREAD_MUTEX_DEFAULT
, global
);
95 /* This already registers a pool cleanup */
98 apr_pool_cleanup_register(global
, NULL
, apu_dso_term
,
99 apr_pool_cleanup_null
);
101 #endif /* APU_DSO_BUILD */
105 apr_status_t
apu_dso_load(apr_dso_handle_sym_t
*dsoptr
, const char *module
,
106 const char *modsym
, apr_pool_t
*pool
)
111 apr_dso_handle_t
*dlhandle
= NULL
;
113 char path
[APR_PATH_MAX
+ 1];
114 apr_array_header_t
*paths
;
116 apr_status_t rv
= APR_EDSOOPEN
;
120 *dsoptr
= apr_hash_get(dsos
, module
, APR_HASH_KEY_STRING
);
125 /* The driver DSO must have exactly the same lifetime as the
126 * drivers hash table; ignore the passed-in pool */
127 global
= apr_hash_pool_get(dsos
);
129 /* Retrieve our path search list or prepare for a single search */
130 if ((apr_env_get(&pathlist
, APR_DSOPATH
, pool
) != APR_SUCCESS
)
131 || (apr_filepath_list_split(&paths
, pathlist
, pool
) != APR_SUCCESS
))
132 paths
= apr_array_make(pool
, 1, sizeof(char*));
134 #if defined(APU_DSO_LIBDIR)
135 /* Always search our prefix path, but on some platforms such as
136 * win32 this may be left undefined
138 (*((char **)apr_array_push(paths
))) = APU_DSO_LIBDIR
;
141 for (i
= 0; i
< paths
->nelts
; ++i
)
144 /* Use win32 dso search semantics and attempt to
145 * load the relative lib on the first pass.
154 eos
= apr_cpystrn(path
, ((char**)paths
->elts
)[i
], sizeof(path
));
155 if ((eos
> path
) && (eos
- path
< sizeof(path
) - 1))
158 apr_cpystrn(eos
, module
, sizeof(path
) - (eos
- path
));
160 rv
= apr_dso_load(&dlhandle
, path
, global
);
161 if (rv
== APR_SUCCESS
) { /* APR_EDSOOPEN */
166 if (rv
!= APR_SUCCESS
) /* APR_ESYMNOTFOUND */
169 rv
= apr_dso_sym(dsoptr
, dlhandle
, modsym
);
170 if (rv
!= APR_SUCCESS
) { /* APR_ESYMNOTFOUND */
171 apr_dso_unload(dlhandle
);
174 module
= apr_pstrdup(global
, module
);
175 apr_hash_set(dsos
, module
, APR_HASH_KEY_STRING
, *dsoptr
);
178 #endif /* APU_DSO_BUILD */