[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: Ramkumar Ramachandra <artagnon_at_gmail.com>
Date: Sat, 8 Jan 2011 16:06:01 +0530

Hi Daniel,

Daniel Shahaf writes:
> Ping, this doesn't seem to have been fixed yet?

Thanks for the ping, and sorry about the delay. I think this should
work -- I'll write a commit message if you think this is okay.

Index: subversion/libsvn_subr/io.c
===================================================================
--- subversion/libsvn_subr/io.c (revision 1056662)
+++ subversion/libsvn_subr/io.c (working copy)
@@ -1299,59 +1299,64 @@ reown_file(const char *path,
   return svn_error_return(svn_io_remove_file2(unique_name, FALSE, pool));
 }
 
-/* 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
- to get at the current value of the umask, so what we're doing here is
- the only way we have to determine which combination of write bits
- (User/Group/World) should be set by default.
- Make temporary allocations in SCRATCH_POOL. */
+/* the default permissions as read from the temp folder */
+static volatile apr_fileperms_t default_perms = 0;
+static volatile svn_atomic_t perms_init_state;
+
+/* Helper function to set default permissions. Passed to svn_atomic__init_once */
 static svn_error_t *
-get_default_file_perms(apr_fileperms_t *perms, apr_pool_t *scratch_pool)
+set_default_perms(void *baton, apr_pool_t *scratch_pool)
 {
- /* the default permissions as read from the temp folder */
- static apr_fileperms_t default_perms = 0;
+ apr_fileperms_t *default_perms = (apr_fileperms_t *) 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;
+ if (default_perms != 0)
+ /* Nothing to do */
+ return SVN_NO_ERROR;
 
- /* Get the perms for a newly created file to find out what bits
- should be set.
+ apr_finfo_t finfo;
+ apr_file_t *fd;
 
- 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.
+ /* Get the perms for a newly created file to find out what bits
+ should be set.
 
- 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.
+ 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.
 
- 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));
+ 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.
 
- *perms = finfo.protection;
- default_perms = finfo.protection;
- }
- else
- *perms = default_perms;
+ 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));
+ 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
+ to get at the current value of the umask, so what we're doing here is
+ the only way we have to determine which combination of write bits
+ (User/Group/World) should be set by default.
+ Make temporary allocations in SCRATCH_POOL. */
+static svn_error_t *
+get_default_file_perms(apr_fileperms_t *perms, apr_pool_t *scratch_pool)
+{
+ SVN_ERR(svn_atomic__init_once(&perms_init_state, set_default_perms,
+ default_perms, scratch_pool));
+ *perms = default_perms;
+ return SVN_NO_ERROR;
+}
+
 /* OR together permission bits of the file FD and the default permissions
    of a file as determined by get_default_file_perms(). Do temporary
    allocations in SCRATCH_POOL. */
Received on 2011-01-08 11:35:47 CET

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