/* 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: 466585 $, $Date: 2006-10-22 00:16:34 +0200 (Sun, 22 Oct 2006) $ */ #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(); }