Garrett Rooney wrote:
> there are actually two states we need to worry about. the first is
> 'have we been canceled', which tells SVN_ERR and SVN_ERR_W to return
> an SVN_ERR_CANCELED error, and the second is 'are we in the process of
> backing out because we received a cancelation', which causes
> svn_error_clear_all to return an SVN_ERR_CANCELED error.
You only need the one state. Here's the pseudocode:
# global state
apr_atomic_t svn_cancelled = false
apr_mutex_t svn_cancellation_mutex
apr_pool_t *svn_cancellation_pool = null
# public interfaces
def svn_async_cancel(pool):
svn_cancellation_mutex.lock()
apr_atoomic_set(svn_canceled, true)
if svn_cancellation_pool is not null:
svn_cancellation_pool = pool;
pool.register_cleanup(lamba x: *x = null, &svn_cancellation_pool)
svn_cancellation_mutex.unlock()
def svn_async_cancel_clear():
svn_cancellation_mutex.lock()
apr_atoomic_set(svn_canceled, false)
svn_cancellation_pool = null
svn_cancellation_mutex.unlock()
def SVN_ERR(err):
if apr_atomic_get(svn_canceled):
return svn_error_cancel(err)
if err is not null:
return err
def SVN_ERR_W(err, msg):
if apr_atomic_get(svn_canceled):
return svn_error_cancel(err)
if err is not null:
return svn_error_quick_wrap(err, msg)
def svn_error_clear_all(err):
if apr_atomic_get(svn_canceled):
return svn_error_cancel(err)
# clean up errors, etc.
def svn_error_cancel(err):
if err is not null:
# Just propagate cancellation errors
if err->svn_err is SVN_ERR_CANCELLED:
return err
return svn_error_create(SVN_ERR_CANCELLED, err->pool)
svn_cancellation_mutex.lock()
if svn_cancellation_pool is null:
# Oops, a race condition? help! WE have to document that when
# you call svn_async_cancel, you should _not_ call svn_async_clear
# until you're absolutely sure your working threads have processed
# the cancellation. You can't cancel a cancel!
abort()
err = svn_error_create(SVN_ERR_CANCELLED, svn_cancellation_pool)
svn_cancellation_mutex.unlock()
return err
Regarding the implementation of svn_err_cancel and error locations: Look
at how the other error creation routines are implemented, and note that
svn_error.c undefines the macro wrappers first. With this
implementation, the SVN_ERR_CANCELLED errors will have correct location
info (i.e., they'll come from the SVN_ERR macros). It would make sense
to create a location wrapper for svn_error_clear_all, too; and note that
you should pass the incoming error to svn_error_create_all, so that we
don't get duplicate SVN_ERR_CANCELLED errors.
--
Brane Čibej <brane_at_xbc.nu> http://www.xbc.nu/brane/
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Sep 14 02:37:30 2002