[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: svn commit: r1004286 - in /subversion/trunk: ./ subversion/libsvn_subr/io.c

From: Daniel Shahaf <d.s_at_daniel.shahaf.name>
Date: Tue, 11 Jan 2011 18:34:57 +0200

I believe this is semantically correct.

Ramkumar, Julian: is the struct still needed? IIRC the reasons for
originally introducing (namely the 'volatile' qualifier) it have since
disappeared.

Daniel

Ramkumar Ramachandra wrote on Tue, Jan 11, 2011 at 21:33:33 +0530:
> Hi Julian and Daniel,
>
> Here's another revision after your suggestions on IRC. Thanks.
>
> [[[
> Determine default perms in an elegant thread-safe way, not racily.
>
> * subversion/libsvn_subr/io.c
>
> (default_perms_baton, perms_init_state): New struct, variable.
>
> (get_default_file_perms): Remove all functional code into
> init_default_file_perms, and use apr_atomic__init_once so that code
> is only executed once.
>
> (init_default_file_perms): New function to determine default file
> permissions by creating a temporary file and extracting permissions
> from it. Default permissions are not determined racily anymore,
> since this function is an apr_atomic__init_once callback.
> ]]]
>
> Index: subversion/libsvn_subr/io.c
> ===================================================================
> --- subversion/libsvn_subr/io.c (revision 1057166)
> +++ subversion/libsvn_subr/io.c (working copy)
> @@ -1300,6 +1300,39 @@ reown_file(const char *path,
> return svn_error_return(svn_io_remove_file2(unique_name, FALSE, pool));
> }
>
> +static volatile svn_atomic_t perms_init_state = 0;
> +struct default_perms_baton
> +{
> + apr_fileperms_t *default_perms;
> +};
> +
> +
> +/* Helper function to discover default file permissions; it does this
> + by creating a temporary file and extracting the permissions from
> + it. Passed to svn_atomic__init_once. All temporary allocations are
> + done in SCRATCH_POOL. */
> +static svn_error_t *
> +init_default_file_perms(void *baton, apr_pool_t *scratch_pool)
> +{
> + apr_fileperms_t *default_perms =
> + ((struct default_perms_baton *) baton)->default_perms;
> + apr_finfo_t finfo;
> + apr_file_t *fd;
> +
> + if (*default_perms != 0)
> + /* Nothing to do */
> + return SVN_NO_ERROR;
> +
> + SVN_ERR(svn_io_open_uniquely_named(&fd, NULL, NULL, "svn-tempfile", ".tmp",
> + svn_io_file_del_on_pool_cleanup,
> + scratch_pool, scratch_pool));
> + SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_PROT, fd, scratch_pool));
> + SVN_ERR(svn_io_file_close(fd, scratch_pool));
> + *default_perms = finfo.protection;
> +
> + return SVN_NO_ERROR;
> +}
> +
> /* Determine what the PERMS for a new file should be by looking at the
> permissions of a temporary file that we create.
> Unfortunately, umask() as defined in POSIX provides no thread-safe way
> @@ -1310,46 +1343,13 @@ reown_file(const char *path,
> static svn_error_t *
> get_default_file_perms(apr_fileperms_t *perms, apr_pool_t *scratch_pool)
> {
> - /* the default permissions as read from the temp folder */
> static apr_fileperms_t default_perms = 0;
> + struct default_perms_baton baton;
>
> - /* Technically, this "racy": Multiple threads may use enter here and
> - try to figure out the default permisission concurrently. That's fine
> - since they will end up with the same results. Even more technical,
> - apr_fileperms_t is an atomic type on 32+ bit machines.
> - */
> - if (default_perms == 0)
> - {
> - apr_finfo_t finfo;
> - apr_file_t *fd;
> -
> - /* Get the perms for a newly created file to find out what bits
> - should be set.
> -
> - Normally del_on_close can be problematic because APR might
> - delete the file if we spawned any child processes. In this
> - case, the lifetime of this file handle is about 3 lines of
> - code, so we can safely use del_on_close here.
> -
> - Not so fast! If some other thread forks off a child, then the
> - APR cleanups run, and the file will disappear. So use
> - del_on_pool_cleanup instead.
> -
> - Using svn_io_open_uniquely_named() here because other tempfile
> - creation functions tweak the permission bits of files they create.
> - */
> - SVN_ERR(svn_io_open_uniquely_named(&fd, NULL, NULL, "svn-tempfile", ".tmp",
> - svn_io_file_del_on_pool_cleanup,
> - scratch_pool, scratch_pool));
> - SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_PROT, fd, scratch_pool));
> - SVN_ERR(svn_io_file_close(fd, scratch_pool));
> -
> - *perms = finfo.protection;
> - default_perms = finfo.protection;
> - }
> - else
> - *perms = default_perms;
> -
> + baton.default_perms = &default_perms;
> + SVN_ERR(svn_atomic__init_once(&perms_init_state, init_default_file_perms,
> + &baton, scratch_pool));
> + *perms = default_perms;
> return SVN_NO_ERROR;
> }
>
Received on 2011-01-11 17:38:57 CET

This is an archived mail posted to the Subversion Dev mailing list.