| /* Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* |
| * |
| * @author Mladen Turk |
| * @version $Revision$, $Date$ |
| */ |
| |
| #include "tcn.h" |
| |
| extern apr_pool_t *tcn_global_pool; |
| |
| static apr_status_t generic_pool_cleanup(void *data) |
| { |
| apr_status_t rv = APR_SUCCESS; |
| tcn_callback_t *cb = (tcn_callback_t *)data; |
| |
| if (data) { |
| JNIEnv *env; |
| tcn_get_java_env(&env); |
| if (!TCN_IS_NULL(env, cb->obj)) { |
| rv = (*(env))->CallIntMethod(env, cb->obj, cb->mid[0], |
| NULL); |
| TCN_UNLOAD_CLASS(env, cb->obj); |
| } |
| free(cb); |
| } |
| return rv; |
| } |
| |
| TCN_IMPLEMENT_CALL(jlong, Pool, create)(TCN_STDARGS, jlong parent) |
| { |
| apr_pool_t *p = J2P(parent, apr_pool_t *); |
| apr_pool_t *n; |
| |
| UNREFERENCED(o); |
| /* Make sure our global pool is accessor for all pools */ |
| if (p == NULL) |
| p = tcn_global_pool; |
| TCN_THROW_IF_ERR(apr_pool_create(&n, p), n); |
| cleanup: |
| return P2J(n); |
| } |
| |
| TCN_IMPLEMENT_CALL(void, Pool, clear)(TCN_STDARGS, jlong pool) |
| { |
| apr_pool_t *p = J2P(pool, apr_pool_t *); |
| UNREFERENCED_STDARGS; |
| TCN_ASSERT(pool != 0); |
| apr_pool_clear(p); |
| } |
| |
| TCN_IMPLEMENT_CALL(void, Pool, destroy)(TCN_STDARGS, jlong pool) |
| { |
| apr_pool_t *p = J2P(pool, apr_pool_t *); |
| UNREFERENCED_STDARGS; |
| TCN_ASSERT(pool != 0); |
| apr_pool_destroy(p); |
| } |
| |
| TCN_IMPLEMENT_CALL(jlong, Pool, parentGet)(TCN_STDARGS, jlong pool) |
| { |
| apr_pool_t *p = J2P(pool, apr_pool_t *); |
| UNREFERENCED_STDARGS; |
| TCN_ASSERT(pool != 0); |
| return P2J(apr_pool_parent_get(p)); |
| } |
| |
| TCN_IMPLEMENT_CALL(jboolean, Pool, isAncestor)(TCN_STDARGS, jlong a, jlong b) |
| { |
| apr_pool_t *pa = J2P(a, apr_pool_t *); |
| apr_pool_t *pb = J2P(b, apr_pool_t *); |
| UNREFERENCED_STDARGS; |
| return apr_pool_is_ancestor(pa, pb) ? JNI_TRUE : JNI_FALSE; |
| } |
| |
| TCN_IMPLEMENT_CALL(jlong, Pool, palloc)(TCN_STDARGS, jlong pool, jint size) |
| { |
| apr_pool_t *p = J2P(pool, apr_pool_t *); |
| UNREFERENCED_STDARGS; |
| return P2J(apr_palloc(p, (apr_size_t)size)); |
| } |
| |
| TCN_IMPLEMENT_CALL(jlong, Pool, pcalloc)(TCN_STDARGS, jlong pool, jint size) |
| { |
| apr_pool_t *p = J2P(pool, apr_pool_t *); |
| UNREFERENCED_STDARGS; |
| return P2J(apr_pcalloc(p, (apr_size_t)size)); |
| } |
| |
| TCN_IMPLEMENT_CALL(jlong, Pool, cleanupRegister)(TCN_STDARGS, jlong pool, |
| jobject obj) |
| { |
| apr_pool_t *p = J2P(pool, apr_pool_t *); |
| tcn_callback_t *cb = (tcn_callback_t *)malloc(sizeof(tcn_callback_t)); |
| jclass cls; |
| |
| UNREFERENCED(o); |
| |
| if (cb == NULL) { |
| TCN_THROW_OS_ERROR(e); |
| return 0; |
| } |
| cls = (*e)->GetObjectClass(e, obj); |
| cb->obj = (*e)->NewGlobalRef(e, obj); |
| cb->mid[0] = (*e)->GetMethodID(e, cls, "callback", "()I"); |
| |
| apr_pool_cleanup_register(p, (const void *)cb, |
| generic_pool_cleanup, |
| apr_pool_cleanup_null); |
| |
| return P2J(cb); |
| } |
| |
| TCN_IMPLEMENT_CALL(void, Pool, cleanupKill)(TCN_STDARGS, jlong pool, |
| jlong data) |
| { |
| apr_pool_t *p = J2P(pool, apr_pool_t *); |
| tcn_callback_t *cb = J2P(data, tcn_callback_t *); |
| |
| UNREFERENCED(o); |
| TCN_ASSERT(pool != 0); |
| apr_pool_cleanup_kill(p, cb, generic_pool_cleanup); |
| (*e)->DeleteGlobalRef(e, cb->obj); |
| free(cb); |
| } |
| |
| TCN_IMPLEMENT_CALL(jobject, Pool, alloc)(TCN_STDARGS, jlong pool, |
| jint size) |
| { |
| apr_pool_t *p = J2P(pool, apr_pool_t *); |
| apr_size_t sz = (apr_size_t)size; |
| void *mem; |
| |
| UNREFERENCED(o); |
| TCN_ASSERT(pool != 0); |
| |
| if ((mem = apr_palloc(p, sz)) != NULL) |
| return (*e)->NewDirectByteBuffer(e, mem, (jlong)sz); |
| else |
| return NULL; |
| } |
| |
| TCN_IMPLEMENT_CALL(jobject, Pool, calloc)(TCN_STDARGS, jlong pool, |
| jint size) |
| { |
| apr_pool_t *p = J2P(pool, apr_pool_t *); |
| apr_size_t sz = (apr_size_t)size; |
| void *mem; |
| |
| UNREFERENCED(o); |
| TCN_ASSERT(pool != 0); |
| |
| if ((mem = apr_pcalloc(p, sz)) != NULL) |
| return (*e)->NewDirectByteBuffer(e, mem, (jlong)sz); |
| else |
| return NULL; |
| } |
| |
| static apr_status_t generic_pool_data_cleanup(void *data) |
| { |
| apr_status_t rv = APR_SUCCESS; |
| tcn_callback_t *cb = (tcn_callback_t *)data; |
| |
| if (data) { |
| JNIEnv *env; |
| tcn_get_java_env(&env); |
| |
| if (!TCN_IS_NULL(env, cb->obj)) { |
| TCN_UNLOAD_CLASS(env, cb->obj); |
| } |
| free(cb); |
| } |
| return rv; |
| } |
| |
| TCN_IMPLEMENT_CALL(jint, Pool, dataSet)(TCN_STDARGS, jlong pool, |
| jstring key, jobject data) |
| { |
| apr_pool_t *p = J2P(pool, apr_pool_t *); |
| apr_status_t rv = APR_SUCCESS; |
| void *old = NULL; |
| TCN_ALLOC_CSTRING(key); |
| |
| UNREFERENCED(o); |
| TCN_ASSERT(pool != 0); |
| |
| if (apr_pool_userdata_get(&old, J2S(key), p) == APR_SUCCESS) { |
| if (old) |
| apr_pool_cleanup_run(p, old, generic_pool_data_cleanup); |
| } |
| if (data) { |
| JNIEnv *e; |
| tcn_callback_t *cb = (tcn_callback_t *)malloc(sizeof(tcn_callback_t)); |
| tcn_get_java_env(&e); |
| cb->obj = (*e)->NewGlobalRef(e, data); |
| if ((rv = apr_pool_userdata_set(cb, J2S(key), generic_pool_data_cleanup, |
| p)) != APR_SUCCESS) { |
| (*e)->DeleteGlobalRef(e, cb->obj); |
| free(cb); |
| } |
| } |
| else { |
| /* Clear the exiting user data */ |
| rv = apr_pool_userdata_set(NULL, J2S(key), NULL, p); |
| } |
| TCN_FREE_CSTRING(key); |
| return rv; |
| } |
| |
| TCN_IMPLEMENT_CALL(jobject, Pool, dataGet)(TCN_STDARGS, jlong pool, |
| jstring key) |
| { |
| apr_pool_t *p = J2P(pool, apr_pool_t *); |
| void *old = NULL; |
| TCN_ALLOC_CSTRING(key); |
| jobject rv = NULL; |
| |
| UNREFERENCED(o); |
| TCN_ASSERT(pool != 0); |
| |
| if (apr_pool_userdata_get(&old, J2S(key), p) == APR_SUCCESS) { |
| if (old) { |
| tcn_callback_t *cb = (tcn_callback_t *)old; |
| rv = cb->obj; |
| } |
| } |
| TCN_FREE_CSTRING(key); |
| return rv; |
| } |
| |
| TCN_IMPLEMENT_CALL(void, Pool, cleanupForExec)(TCN_STDARGS) |
| { |
| UNREFERENCED_STDARGS; |
| apr_pool_cleanup_for_exec(); |
| } |