Author: pburba Date: Fri Aug 5 18:49:28 2011 New Revision: 1154351 URL: http://svn.apache.org/viewvc?rev=1154351&view=rev Log: On the issue-3975 branch: Sync with ^/subversion/trunk.
Modified: subversion/branches/issue-3975/ (props changed) subversion/branches/issue-3975/build/run_tests.py subversion/branches/issue-3975/subversion/bindings/javahl/native/ClientContext.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/ClientContext.h subversion/branches/issue-3975/subversion/bindings/javahl/native/CopySources.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/CopySources.h subversion/branches/issue-3975/subversion/bindings/javahl/native/File.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/InputStream.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIThreadData.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIThreadData.h subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIUtil.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIUtil.h subversion/branches/issue-3975/subversion/bindings/javahl/native/OutputStream.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/Path.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/Path.h subversion/branches/issue-3975/subversion/bindings/javahl/native/Pool.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/Pool.h subversion/branches/issue-3975/subversion/bindings/javahl/native/Prompter.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/Prompter.h subversion/branches/issue-3975/subversion/bindings/javahl/native/RevisionRange.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/RevpropTable.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNBase.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNBase.h subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNClient.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNRepos.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/StringArray.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/Targets.cpp subversion/branches/issue-3975/subversion/bindings/javahl/native/Targets.h subversion/branches/issue-3975/subversion/bindings/javahl/native/libsvnjavahl.la.c subversion/branches/issue-3975/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp subversion/branches/issue-3975/subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.java subversion/branches/issue-3975/subversion/libsvn_client/cmdline.c subversion/branches/issue-3975/subversion/libsvn_client/merge.c subversion/branches/issue-3975/subversion/libsvn_ra_serf/ra_serf.h subversion/branches/issue-3975/subversion/libsvn_ra_serf/serf.c subversion/branches/issue-3975/subversion/svn/main.c subversion/branches/issue-3975/subversion/svnrdump/svnrdump.c subversion/branches/issue-3975/subversion/tests/cmdline/merge_tests.py Propchange: subversion/branches/issue-3975/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Fri Aug 5 18:49:28 2011 @@ -54,4 +54,4 @@ /subversion/branches/tree-conflicts:868291-873154 /subversion/branches/tree-conflicts-notify:873926-874008 /subversion/branches/uris-as-urls:1060426-1064427 -/subversion/trunk:1152931-1153938 +/subversion/trunk:1152931-1154347 Modified: subversion/branches/issue-3975/build/run_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/build/run_tests.py?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/build/run_tests.py (original) +++ subversion/branches/issue-3975/build/run_tests.py Fri Aug 5 18:49:28 2011 @@ -453,11 +453,16 @@ class TestHarness: else: test_selection = [] - failed = svntest.main.execute_tests(prog_mod.test_list, - serial_only=serial_only, - test_name=progbase, - progress_func=prog_f, - test_selection=test_selection) + try: + failed = svntest.main.execute_tests(prog_mod.test_list, + serial_only=serial_only, + test_name=progbase, + progress_func=prog_f, + test_selection=test_selection) + except svntest.Failure: + if self.log: + os.write(old_stdout, '.' * dot_count) + failed = True # restore some values sys.path = old_path Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/ClientContext.cpp URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/ClientContext.cpp?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/ClientContext.cpp (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/ClientContext.cpp Fri Aug 5 18:49:28 2011 @@ -38,12 +38,11 @@ #include "CommitMessage.h" -ClientContext::ClientContext(jobject jsvnclient) +ClientContext::ClientContext(jobject jsvnclient, SVN::Pool &pool) : m_prompter(NULL), m_cancelOperation(false) { JNIEnv *env = JNIUtil::getEnv(); - JNICriticalSection criticalSection(*JNIUtil::getGlobalPoolMutex()); /* Grab a global reference to the Java object embedded in the parent Java object. */ @@ -72,23 +71,32 @@ ClientContext::ClientContext(jobject jsv env->DeleteLocalRef(jctx); - /* Create a long-lived client context object in the global pool. */ - SVN_JNI_ERR(svn_client_create_context(&persistentCtx, JNIUtil::getPool()), + SVN_JNI_ERR(svn_client_create_context(&m_context, pool.getPool()), ); + /* Clear the wc_ctx as we don't want to maintain this unconditionally + for compatibility reasons */ + SVN_JNI_ERR(svn_wc_context_destroy(m_context->wc_ctx), + ); + m_context->wc_ctx = NULL; + /* None of the following members change during the lifetime of this object. */ - persistentCtx->notify_func = NULL; - persistentCtx->notify_baton = NULL; - persistentCtx->log_msg_func3 = CommitMessage::callback; - persistentCtx->cancel_func = checkCancel; - persistentCtx->cancel_baton = this; - persistentCtx->notify_func2= notify; - persistentCtx->notify_baton2 = m_jctx; - persistentCtx->progress_func = progress; - persistentCtx->progress_baton = m_jctx; - persistentCtx->conflict_func2 = resolve; - persistentCtx->conflict_baton2 = m_jctx; + m_context->notify_func = NULL; + m_context->notify_baton = NULL; + m_context->log_msg_func3 = CommitMessage::callback; + m_context->log_msg_baton3 = NULL; + m_context->cancel_func = checkCancel; + m_context->cancel_baton = this; + m_context->notify_func2= notify; + m_context->notify_baton2 = m_jctx; + m_context->progress_func = progress; + m_context->progress_baton = m_jctx; + m_context->conflict_func2 = resolve; + m_context->conflict_baton2 = m_jctx; + + m_context->client_name = "javahl"; + m_pool = &pool; } ClientContext::~ClientContext() @@ -99,23 +107,70 @@ ClientContext::~ClientContext() env->DeleteGlobalRef(m_jctx); } + +/* Helper function to make sure that we don't keep dangling pointers in ctx. + Note that this function might be called multiple times if getContext() + is called on the same pool. + + The use of this function assumes a proper subpool behavior by its user, + (read: SVNClient) usually per request. + */ +extern "C" { + +struct clearctx_baton_t +{ + svn_client_ctx_t *ctx; + svn_client_ctx_t *backup; +}; + +static apr_status_t clear_ctx_ptrs(void *ptr) +{ + clearctx_baton_t *bt = (clearctx_baton_t*)ptr; + + /* Reset all values to those before overwriting by getContext. */ + *bt->ctx = *bt->backup; + + return APR_SUCCESS; +} + +}; + svn_client_ctx_t * -ClientContext::getContext(CommitMessage *message) +ClientContext::getContext(CommitMessage *message, SVN::Pool &in_pool) { - SVN::Pool *requestPool = JNIUtil::getRequestPool(); - apr_pool_t *pool = requestPool->pool(); + apr_pool_t *pool = in_pool.getPool(); svn_auth_baton_t *ab; - svn_client_ctx_t *ctx = persistentCtx; - //SVN_JNI_ERR(svn_client_create_context(&ctx, pool), NULL); + svn_client_ctx_t *ctx = m_context; + + /* Make a temporary copy of ctx to restore at pool cleanup to avoid + leaving references to dangling pointers. - const char *configDir = m_configDir.c_str(); - if (m_configDir.length() == 0) - configDir = NULL; - SVN_JNI_ERR(svn_config_get_config(&(ctx->config), configDir, pool), NULL); + Note that this allows creating a stack of context changes if + the function is invoked multiple times with different pools. + */ + clearctx_baton_t *bt = (clearctx_baton_t *)apr_pcalloc(pool, sizeof(*bt)); + bt->ctx = ctx; + bt->backup = (svn_client_ctx_t*)apr_pmemdup(pool, ctx, sizeof(*ctx)); + apr_pool_cleanup_register(in_pool.getPool(), bt, clear_ctx_ptrs, + clear_ctx_ptrs); + + + if (!ctx->config) + { + const char *configDir = m_configDir.c_str(); + if (m_configDir.empty()) + configDir = NULL; + SVN_JNI_ERR(svn_config_get_config(&(ctx->config), configDir, + m_pool->getPool()), + NULL); + + bt->backup->config = ctx->config; + } svn_config_t *config = (svn_config_t *) apr_hash_get(ctx->config, SVN_CONFIG_CATEGORY_CONFIG, APR_HASH_KEY_STRING); + /* The whole list of registered providers */ apr_array_header_t *providers; @@ -173,22 +228,22 @@ ClientContext::getContext(CommitMessage if (m_prompter != NULL) { /* Two basic prompt providers: username/password, and just username.*/ - provider = m_prompter->getProviderSimple(); + provider = m_prompter->getProviderSimple(in_pool); APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - provider = m_prompter->getProviderUsername(); + provider = m_prompter->getProviderUsername(in_pool); APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; /* Three ssl prompt providers, for server-certs, client-certs, * and client-cert-passphrases. */ - provider = m_prompter->getProviderServerSSLTrust(); + provider = m_prompter->getProviderServerSSLTrust(in_pool); APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - provider = m_prompter->getProviderClientSSL(); + provider = m_prompter->getProviderClientSSL(in_pool); APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - provider = m_prompter->getProviderClientSSLPassword(); + provider = m_prompter->getProviderClientSSLPassword(in_pool); APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; } @@ -199,15 +254,26 @@ ClientContext::getContext(CommitMessage * auth_baton's run-time parameter hash. ### Same with --no-auth-cache? */ if (!m_userName.empty()) svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_USERNAME, - m_userName.c_str()); + apr_pstrdup(in_pool.getPool(), + m_userName.c_str())); if (!m_passWord.empty()) svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_PASSWORD, - m_passWord.c_str()); + apr_pstrdup(in_pool.getPool(), + m_passWord.c_str())); + /* Store where to retrieve authentication data? */ + if (!m_configDir.empty()) + svn_auth_set_parameter(ab, SVN_AUTH_PARAM_CONFIG_DIR, + apr_pstrdup(in_pool.getPool(), + m_configDir.c_str())); ctx->auth_baton = ab; ctx->log_msg_baton3 = message; m_cancelOperation = false; + SVN_JNI_ERR(svn_wc_context_create(&ctx->wc_ctx, NULL, + in_pool.getPool(), in_pool.getPool()), + NULL); + return ctx; } @@ -236,9 +302,10 @@ ClientContext::setConfigDirectory(const // A change to the config directory may necessitate creation of // the config templates. SVN::Pool requestPool; - SVN_JNI_ERR(svn_config_ensure(configDir, requestPool.pool()), ); + SVN_JNI_ERR(svn_config_ensure(configDir, requestPool.getPool()), ); m_configDir = (configDir == NULL ? "" : configDir); + m_context->config = NULL; } const char * @@ -386,7 +453,8 @@ ClientContext::resolve(svn_wc_conflict_r { // If an exception is thrown by our conflict resolver, remove it // from the JNI env, and convert it into a Subversion error. - const char *msg = JNIUtil::thrownExceptionToCString(); + SVN::Pool tmpPool(scratch_pool); + const char *msg = JNIUtil::thrownExceptionToCString(tmpPool); svn_error_t *err = svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL, msg); env->PopLocalFrame(NULL); Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/ClientContext.h URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/ClientContext.h?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/ClientContext.h (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/ClientContext.h Fri Aug 5 18:49:28 2011 @@ -42,11 +42,13 @@ class CommitMessage; /** * This class contains a Java objects implementing the interface ClientContext * and implements the functions read & close of svn_stream_t. + * */ class ClientContext { private: - svn_client_ctx_t *persistentCtx; + svn_client_ctx_t *m_context; + const SVN::Pool *m_pool; jobject m_jctx; std::string m_userName; @@ -70,12 +72,12 @@ class ClientContext apr_pool_t *pool); public: - ClientContext(jobject jsvnclient); + ClientContext(jobject jsvnclient, SVN::Pool &pool); ~ClientContext(); static svn_error_t *checkCancel(void *cancelBaton); - svn_client_ctx_t *getContext(CommitMessage *message); + svn_client_ctx_t *getContext(CommitMessage *message, SVN::Pool &in_pool); void username(const char *pi_username); void password(const char *pi_password); Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/CopySources.cpp URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/CopySources.cpp?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/CopySources.cpp (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/CopySources.cpp Fri Aug 5 18:49:28 2011 @@ -85,7 +85,7 @@ CopySources::makeJCopySource(const char apr_array_header_t * CopySources::array(SVN::Pool &pool) { - apr_pool_t *p = pool.pool(); + apr_pool_t *p = pool.getPool(); JNIEnv *env = JNIUtil::getEnv(); jclass clazz = env->FindClass(JAVA_PACKAGE "/types/CopySource"); @@ -122,7 +122,7 @@ CopySources::array(SVN::Pool &pool) src->path = apr_pstrdup(p, path); env->ReleaseStringUTFChars(jpath, path); - SVN_JNI_ERR(JNIUtil::preprocessPath(src->path, pool.pool()), + SVN_JNI_ERR(JNIUtil::preprocessPath(src->path, pool.getPool()), NULL); env->DeleteLocalRef(jpath); Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/CopySources.h URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/CopySources.h?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/CopySources.h (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/CopySources.h Fri Aug 5 18:49:28 2011 @@ -71,6 +71,9 @@ class CopySources * A local reference to the Java CopySources peer. */ Array &m_copySources; + + CopySources(const CopySources &from); + CopySources & operator=(const CopySources &); }; #endif /* COPY_SOURCES_H */ Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/File.cpp URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/File.cpp?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/File.cpp (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/File.cpp Fri Aug 5 18:49:28 2011 @@ -90,7 +90,7 @@ const char *File::getInternalStyle(const { const char *path = getAbsPath(); if (path) - return svn_dirent_internal_style(path, requestPool.pool()); + return svn_dirent_internal_style(path, requestPool.getPool()); else return NULL; } Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/InputStream.cpp URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/InputStream.cpp?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/InputStream.cpp (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/InputStream.cpp Fri Aug 5 18:49:28 2011 @@ -53,7 +53,7 @@ svn_stream_t *InputStream::getStream(con { // Create a stream with this as the baton and set the read and // close functions. - svn_stream_t *ret = svn_stream_create(this, pool.pool()); + svn_stream_t *ret = svn_stream_create(this, pool.getPool()); svn_stream_set_read(ret, InputStream::read); svn_stream_set_close(ret, InputStream::close); return ret; Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIThreadData.cpp URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIThreadData.cpp?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIThreadData.cpp (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIThreadData.cpp Fri Aug 5 18:49:28 2011 @@ -41,7 +41,6 @@ JNIThreadData::JNIThreadData() { m_env = NULL; m_exceptionThrown = false; - m_requestPool = NULL; m_previous = NULL; } Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIThreadData.h URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIThreadData.h?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIThreadData.h (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIThreadData.h Fri Aug 5 18:49:28 2011 @@ -61,10 +61,6 @@ class JNIThreadData */ char m_formatBuffer[JNIUtil::formatBufferSize]; - /** - * The pool for the current request (call). - */ - SVN::Pool *m_requestPool; private: /** * Pointer to previous thread information to enable reentrent Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIUtil.cpp URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIUtil.cpp?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIUtil.cpp (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIUtil.cpp Fri Aug 5 18:49:28 2011 @@ -64,7 +64,6 @@ apr_pool_t *JNIUtil::g_pool = NULL; std::list<SVNBase*> JNIUtil::g_finalizedObjects; JNIMutex *JNIUtil::g_finalizedObjectsMutex = NULL; JNIMutex *JNIUtil::g_logMutex = NULL; -JNIMutex *JNIUtil::g_globalPoolMutext = NULL; bool JNIUtil::g_initException; bool JNIUtil::g_inInit; JNIEnv *JNIUtil::g_initEnv; @@ -127,39 +126,7 @@ bool JNIUtil::JNIGlobalInit(JNIEnv *env) apr_status_t status; - /* C programs default to the "C" locale. But because svn is supposed - to be i18n-aware, it should inherit the default locale of its - environment. */ - if (!setlocale(LC_ALL, "")) - { - if (stderr) - { - const char *env_vars[] = { "LC_ALL", "LC_CTYPE", "LANG", NULL }; - const char **env_var = &env_vars[0], *env_val = NULL; - while (*env_var) - { - env_val = getenv(*env_var); - if (env_val && env_val[0]) - break; - ++env_var; - } - if (!*env_var) - { - /* Unlikely. Can setlocale fail if no env vars are set? */ - --env_var; - env_val = "not set"; - } - - fprintf(stderr, - "%s: error: cannot set LC_ALL locale\n" - "%s: error: environment variable %s is %s\n" - "%s: error: please check that your locale name is " - "correct\n", - "svnjavahl", "svnjavahl", *env_var, env_val, "svnjavahl"); - } - return FALSE; - } /* Initialize the APR subsystem, and register an atexit() function * to Uninitialize that subsystem at program exit. */ @@ -196,6 +163,19 @@ bool JNIUtil::JNIGlobalInit(JNIEnv *env) return FALSE; } + /* Create our top-level pool. */ + g_pool = svn_pool_create(NULL); + + apr_allocator_t* allocator = apr_pool_allocator_get(g_pool); + + if (allocator) + { + /* Keep a maximum of 1 free block, to release memory back to the JVM + (and other modules). */ + apr_allocator_max_free_set(allocator, 1); + } + + #ifdef ENABLE_NLS #ifdef WIN32 { @@ -207,7 +187,7 @@ bool JNIUtil::JNIGlobalInit(JNIEnv *env) apr_size_t inwords, outbytes; unsigned int outlength; - apr_pool_create(&pool, 0); + pool = svn_pool_create(g_pool); /* get dll name - our locale info will be in '../share/locale' */ inwords = sizeof(ucs2_path) / sizeof(ucs2_path[0]); HINSTANCE moduleHandle = GetModuleHandle("libsvnjavahl-1"); @@ -232,16 +212,13 @@ bool JNIUtil::JNIGlobalInit(JNIEnv *env) internal_path = svn_dirent_join(internal_path, SVN_LOCALE_RELATIVE_PATH, pool); bindtextdomain(PACKAGE_NAME, internal_path); - apr_pool_destroy(pool); + svn_pool_destroy(pool); } #else bindtextdomain(PACKAGE_NAME, SVN_LOCALE_DIR); #endif #endif - /* Create our top-level pool. */ - g_pool = svn_pool_create(NULL); - #if defined(WIN32) || defined(__CYGWIN__) /* See http://svn.apache.org/repos/asf/subversion/trunk/notes/asp-dot-net-hack.txt */ /* ### This code really only needs to be invoked by consumers of @@ -272,10 +249,6 @@ bool JNIUtil::JNIGlobalInit(JNIEnv *env) if (isExceptionThrown()) return false; - g_globalPoolMutext = new JNIMutex(g_pool); - if (isExceptionThrown()) - return false; - // initialized the thread local storage if (!JNIThreadData::initThreadData()) return false; @@ -298,15 +271,6 @@ apr_pool_t *JNIUtil::getPool() return g_pool; } -/** - * Return the mutex securing the global pool. - * @return the mutex for the global pool - */ -JNIMutex *JNIUtil::getGlobalPoolMutex() -{ - return g_globalPoolMutext; -} - void JNIUtil::raiseThrowable(const char *name, const char *message) { if (getLogLevel() >= errorLog) @@ -655,7 +619,7 @@ bool JNIUtil::isJavaExceptionThrown() } const char * -JNIUtil::thrownExceptionToCString() +JNIUtil::thrownExceptionToCString(SVN::Pool &in_pool) { const char *msg; JNIEnv *env = getEnv(); @@ -672,7 +636,7 @@ JNIUtil::thrownExceptionToCString() } jstring jmsg = (jstring) env->CallObjectMethod(t, getMessage); JNIStringHolder tmp(jmsg); - msg = tmp.pstrdup(getRequestPool()->pool()); + msg = tmp.pstrdup(in_pool.getPool()); // ### Conditionally add t.printStackTrace() to msg? } else @@ -808,25 +772,6 @@ jobject JNIUtil::createDate(apr_time_t t } /** - * Return the request pool. The request pool will be destroyed after each - * request (call). - * @return the pool to be used for this request - */ -SVN::Pool *JNIUtil::getRequestPool() -{ - return JNIThreadData::getThreadData()->m_requestPool; -} - -/** - * Set the request pool in thread local storage. - * @param pool the request pool - */ -void JNIUtil::setRequestPool(SVN::Pool *pool) -{ - JNIThreadData::getThreadData()->m_requestPool = pool; -} - -/** * Create a Java byte array from an array of characters. * @param data the character array * @param length the number of characters in the array Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIUtil.h URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIUtil.h?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIUtil.h (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/JNIUtil.h Fri Aug 5 18:49:28 2011 @@ -63,8 +63,6 @@ class JNIUtil static void throwNullPointerException(const char *message); static jbyteArray makeJByteArray(const signed char *data, int length); - static void setRequestPool(SVN::Pool *pool); - static SVN::Pool *getRequestPool(); static jobject createDate(apr_time_t time); static void logMessage(const char *message); static int getLogLevel(); @@ -103,7 +101,7 @@ class JNIUtil * occurred. Useful for converting Java @c Exceptions into @c * svn_error_t's. */ - static const char *thrownExceptionToCString(); + static const char *thrownExceptionToCString(SVN::Pool &in_pool); /** * Throw a Java exception corresponding to err, and run @@ -135,7 +133,7 @@ class JNIUtil static apr_pool_t *getPool(); static bool JNIGlobalInit(JNIEnv *env); static bool JNIInit(JNIEnv *env); - static JNIMutex *getGlobalPoolMutex(); + static bool initializeJNIRuntime(); enum { formatBufferSize = 2048 }; enum { noLog, errorLog, exceptionLog, entryLog } LogLevel; @@ -202,11 +200,6 @@ class JNIUtil * The stream to write log messages to. */ static std::ofstream g_logStream; - - /** - * Flag to secure our global pool. - */ - static JNIMutex *g_globalPoolMutext; }; /** Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/OutputStream.cpp URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/OutputStream.cpp?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/OutputStream.cpp (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/OutputStream.cpp Fri Aug 5 18:49:28 2011 @@ -56,7 +56,7 @@ svn_stream_t *OutputStream::getStream(co { // Create a stream with this as the baton and set the write and // close functions. - svn_stream_t *ret = svn_stream_create(this, pool.pool()); + svn_stream_t *ret = svn_stream_create(this, pool.getPool()); svn_stream_set_write(ret, OutputStream::write); svn_stream_set_close(ret, OutputStream::close); return ret; Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/Path.cpp URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/Path.cpp?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/Path.cpp (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/Path.cpp Fri Aug 5 18:49:28 2011 @@ -36,9 +36,9 @@ * @see Path::Path(const std::string &) * @param path Path string */ -Path::Path(const char *pi_path) +Path::Path(const char *pi_path, SVN::Pool &in_pool) { - init(pi_path); + init(pi_path, in_pool); } /** @@ -48,9 +48,9 @@ Path::Path(const char *pi_path) * * @param path Path string */ -Path::Path(const std::string &pi_path) +Path::Path(const std::string &pi_path, SVN::Pool &in_pool) { - init(pi_path.c_str()); + init(pi_path.c_str(), in_pool); } /** @@ -58,9 +58,9 @@ Path::Path(const std::string &pi_path) * * @param path Path to be copied */ -Path::Path(const Path &pi_path) +Path::Path(const Path &pi_path, SVN::Pool &in_pool) { - init(pi_path.c_str()); + init(pi_path.c_str(), in_pool); } /** @@ -69,7 +69,7 @@ Path::Path(const Path &pi_path) * @param path Path string */ void -Path::init(const char *pi_path) +Path::init(const char *pi_path, SVN::Pool &in_pool) { if (*pi_path == 0) { @@ -78,9 +78,7 @@ Path::init(const char *pi_path) } else { - m_error_occured = - JNIUtil::preprocessPath(pi_path, - JNIUtil::getRequestPool()->pool() ); + m_error_occured = JNIUtil::preprocessPath(pi_path, in_pool.getPool()); m_path = pi_path; } @@ -110,7 +108,9 @@ Path::c_str() const Path& Path::operator=(const Path &pi_path) { - init(pi_path.c_str()); + m_error_occured = NULL; + m_path = pi_path.m_path; + return *this; } @@ -125,7 +125,7 @@ jboolean Path::isValid(const char *p) return JNI_FALSE; SVN::Pool requestPool; - svn_error_t *err = svn_path_check_valid(p, requestPool.pool()); + svn_error_t *err = svn_path_check_valid(p, requestPool.getPool()); if (err == SVN_NO_ERROR) { return JNI_TRUE; Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/Path.h URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/Path.h?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/Path.h (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/Path.h Fri Aug 5 18:49:28 2011 @@ -29,6 +29,7 @@ #include <string> #include <jni.h> +#include "Pool.h" struct svn_error_t; /** @@ -47,7 +48,7 @@ class Path * * @param pi_path Path string */ - void init(const char *pi_path); + void init(const char *pi_path, SVN::Pool &in_pool); public: /** @@ -57,7 +58,7 @@ class Path * * @param pi_path Path string */ - Path(const std::string &pi_path = ""); + Path(const std::string &pi_path, SVN::Pool &in_pool); /** * Constructor @@ -65,14 +66,14 @@ class Path * @see Path::Path (const std::string &) * @param pi_path Path string */ - Path(const char *pi_path); + Path(const char *pi_path, SVN::Pool &in_pool); /** * Copy constructor * * @param pi_path Path to be copied */ - Path(const Path &pi_path); + Path(const Path &pi_path, SVN::Pool &in_pool); /** * Assignment operator Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/Pool.cpp URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/Pool.cpp?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/Pool.cpp (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/Pool.cpp Fri Aug 5 18:49:28 2011 @@ -31,14 +31,27 @@ #include "svn_pools.h" /** - * Constructor to create one apr pool as the subpool of the global pool - * store this pool as the request pool. + * Constructor to create one apr pool as the subpool of the global pool. */ SVN::Pool::Pool() { - JNICriticalSection criticalSection(*JNIUtil::getGlobalPoolMutex()); m_pool = svn_pool_create(JNIUtil::getPool()); - JNIUtil::setRequestPool(this); +} + +/** + * Constructor to create one apr pool as a subpool of the passed pool. + */ +SVN::Pool::Pool(const Pool &parent_pool) +{ + m_pool = svn_pool_create(parent_pool.m_pool); +} + +/** + * Constructor to create one apr pool as a subpool of the passed pool. + */ +SVN::Pool::Pool(apr_pool_t *parent_pool) +{ + m_pool = svn_pool_create(parent_pool); } /** @@ -47,8 +60,10 @@ SVN::Pool::Pool() */ SVN::Pool::~Pool() { - JNICriticalSection criticalSection(*JNIUtil::getGlobalPoolMutex()); - JNIUtil::setRequestPool(NULL); if (m_pool) - svn_pool_destroy(m_pool); + { + svn_pool_destroy(m_pool); + m_pool = NULL; + } } + Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/Pool.h URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/Pool.h?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/Pool.h (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/Pool.h Fri Aug 5 18:49:28 2011 @@ -39,8 +39,10 @@ namespace SVN { { public: Pool(); + Pool(const Pool &parent_pool); + Pool(apr_pool_t *parent_pool); ~Pool(); - apr_pool_t *pool() const; + apr_pool_t *getPool() const; void clear() const; private: @@ -50,14 +52,14 @@ namespace SVN { apr_pool_t *m_pool; /** - * We declare the copy constructor and assignment operator private - * here, so that the compiler won't inadvertently use them for us. - * The default copy constructor just copies all the data members, - * which would create two pointers to the same pool, one of which - * would get destroyed while the other thought it was still - * valid...and BOOM! Hence the private declaration. + * We declare the assignment operator private here, so that the compiler + * won't inadvertently use them for us. + * The default code just copies all the data members, which would create + * two pointers to the same pool, one of which would get destroyed while + * the other thought it was still valid...and BOOM! + * + * Hence the private declaration. */ - Pool(Pool &that); Pool &operator=(Pool &that); }; @@ -65,7 +67,7 @@ namespace SVN { // need to be implemented in the header file for that to happen. inline - apr_pool_t *Pool::pool() const + apr_pool_t *Pool::getPool() const { return m_pool; } Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/Prompter.cpp URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/Prompter.cpp?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/Prompter.cpp (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/Prompter.cpp Fri Aug 5 18:49:28 2011 @@ -361,9 +361,9 @@ bool Prompter::prompt(const char *realm, return ret ? true:false; } -svn_auth_provider_object_t *Prompter::getProviderSimple() +svn_auth_provider_object_t *Prompter::getProviderSimple(SVN::Pool &in_pool) { - apr_pool_t *pool = JNIUtil::getRequestPool()->pool(); + apr_pool_t *pool = in_pool.getPool(); svn_auth_provider_object_t *provider; svn_auth_get_simple_prompt_provider(&provider, simple_prompt, @@ -374,9 +374,9 @@ svn_auth_provider_object_t *Prompter::ge return provider; } -svn_auth_provider_object_t *Prompter::getProviderUsername() +svn_auth_provider_object_t *Prompter::getProviderUsername(SVN::Pool &in_pool) { - apr_pool_t *pool = JNIUtil::getRequestPool()->pool(); + apr_pool_t *pool = in_pool.getPool(); svn_auth_provider_object_t *provider; svn_auth_get_username_prompt_provider(&provider, username_prompt, @@ -387,9 +387,9 @@ svn_auth_provider_object_t *Prompter::ge return provider; } -svn_auth_provider_object_t *Prompter::getProviderServerSSLTrust() +svn_auth_provider_object_t *Prompter::getProviderServerSSLTrust(SVN::Pool &in_pool) { - apr_pool_t *pool = JNIUtil::getRequestPool()->pool(); + apr_pool_t *pool = in_pool.getPool(); svn_auth_provider_object_t *provider; svn_auth_get_ssl_server_trust_prompt_provider (&provider, ssl_server_trust_prompt, this, pool); @@ -397,9 +397,9 @@ svn_auth_provider_object_t *Prompter::ge return provider; } -svn_auth_provider_object_t *Prompter::getProviderClientSSL() +svn_auth_provider_object_t *Prompter::getProviderClientSSL(SVN::Pool &in_pool) { - apr_pool_t *pool = JNIUtil::getRequestPool()->pool(); + apr_pool_t *pool = in_pool.getPool(); svn_auth_provider_object_t *provider; svn_auth_get_ssl_client_cert_prompt_provider(&provider, ssl_client_cert_prompt, @@ -410,9 +410,9 @@ svn_auth_provider_object_t *Prompter::ge return provider; } -svn_auth_provider_object_t *Prompter::getProviderClientSSLPassword() +svn_auth_provider_object_t *Prompter::getProviderClientSSLPassword(SVN::Pool &in_pool) { - apr_pool_t *pool = JNIUtil::getRequestPool()->pool(); + apr_pool_t *pool = in_pool.getPool(); svn_auth_provider_object_t *provider; svn_auth_get_ssl_client_cert_pw_prompt_provider (&provider, ssl_client_cert_pw_prompt, this, 2 /* retry limit */, Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/Prompter.h URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/Prompter.h?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/Prompter.h (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/Prompter.h Fri Aug 5 18:49:28 2011 @@ -30,7 +30,7 @@ #include <jni.h> #include "svn_auth.h" #include <string> - +#include "Pool.h" /** * This class requests username/password and informations about * ssl-certificates from the user. @@ -96,11 +96,11 @@ class Prompter public: static Prompter *makeCPrompter(jobject jprompter); ~Prompter(); - svn_auth_provider_object_t *getProviderUsername(); - svn_auth_provider_object_t *getProviderSimple(); - svn_auth_provider_object_t *getProviderServerSSLTrust(); - svn_auth_provider_object_t *getProviderClientSSL(); - svn_auth_provider_object_t *getProviderClientSSLPassword(); + svn_auth_provider_object_t *getProviderUsername(SVN::Pool &in_pool); + svn_auth_provider_object_t *getProviderSimple(SVN::Pool &in_pool); + svn_auth_provider_object_t *getProviderServerSSLTrust(SVN::Pool &in_pool); + svn_auth_provider_object_t *getProviderClientSSL(SVN::Pool &in_pool); + svn_auth_provider_object_t *getProviderClientSSLPassword(SVN::Pool &in_pool); static svn_error_t *plaintext_prompt(svn_boolean_t *may_save_plaintext, const char *realmstring, Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/RevisionRange.cpp URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/RevisionRange.cpp?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/RevisionRange.cpp (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/RevisionRange.cpp Fri Aug 5 18:49:28 2011 @@ -87,7 +87,7 @@ const svn_opt_revision_range_t *Revision return NULL; svn_opt_revision_range_t *range = - (svn_opt_revision_range_t *) apr_palloc(pool.pool(), sizeof(*range)); + (svn_opt_revision_range_t *) apr_palloc(pool.getPool(), sizeof(*range)); range->start = *startRevision.revision(); if (JNIUtil::isExceptionThrown()) Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/RevpropTable.cpp URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/RevpropTable.cpp?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/RevpropTable.cpp (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/RevpropTable.cpp Fri Aug 5 18:49:28 2011 @@ -46,15 +46,15 @@ const apr_hash_t *RevpropTable::hash(con if (m_revprops.size() == 0) return NULL; - apr_hash_t *revprop_table = apr_hash_make(pool.pool()); + apr_hash_t *revprop_table = apr_hash_make(pool.getPool()); std::map<std::string, std::string>::const_iterator it; for (it = m_revprops.begin(); it != m_revprops.end(); ++it) { - const char *propname = apr_pstrdup(pool.pool(), it->first.c_str()); + const char *propname = apr_pstrdup(pool.getPool(), it->first.c_str()); if (!svn_prop_name_is_valid(propname)) { - const char *msg = apr_psprintf(pool.pool(), + const char *msg = apr_psprintf(pool.getPool(), "Invalid property name: '%s'", propname); JNIUtil::throwNativeException(JAVA_PACKAGE "/ClientException", msg, @@ -63,7 +63,7 @@ const apr_hash_t *RevpropTable::hash(con } svn_string_t *propval = svn_string_create(it->second.c_str(), - pool.pool()); + pool.getPool()); apr_hash_set(revprop_table, propname, APR_HASH_KEY_STRING, propval); } Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNBase.cpp URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNBase.cpp?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNBase.cpp (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNBase.cpp Fri Aug 5 18:49:28 2011 @@ -28,6 +28,7 @@ #include "JNIUtil.h" SVNBase::SVNBase() + : pool(JNIUtil::getPool()) { jthis = NULL; } Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNBase.h URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNBase.h?rev=1154351&r1=1154350&r2=1154351&view=diff ============================================================================== --- subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNBase.h (original) +++ subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNBase.h Fri Aug 5 18:49:28 2011 @@ -28,6 +28,7 @@ #define SVNBASE_H #include <jni.h> +#include "Pool.h" class SVNBase { @@ -96,6 +97,9 @@ class SVNBase */ static void findCppAddrFieldID(jfieldID *fid, const char *className, JNIEnv *env); + +protected: + SVN::Pool pool; }; #endif // SVNBASE_H