Thread-safe FileUtils.cd

J

James Coglan

[Note: parts of this message were removed to make it a legal post.]

Hi all,

I have a build tool that I've written in Ruby that uses this construct to
enter a directory, perform some long-running (several seconds) tasks then
exit back to the original working directory:

FileUtils.cd(dir) do
# expensive operations
end

Now I'm trying to write another tool that uses this build library to run
several builds at once in different Threads. Problem is, the FileUtils.cd
commands overlap and conflict with each other, causing the builds to fail. I
have a lot of code already out in production that relies on this directory
being set correctly (users can write hooks into the build system, and these
hooks assume a certain working directory), so I can't remove the cd() call.

My question is, is there a way of setting the working directory on a
per-thread basis, or is it a global property of the Ruby process that cannot
be made thread-safe?

Cheers,
James
 
M

Markus Schirp

The current working process is a global property of the underlaying
system process.

A system Process has one currency working directory, not two, or more.

You can do your directory / filename calculations, using the absolute
directory path, without any race conditions.
 
J

James Coglan

[Note: parts of this message were removed to make it a legal post.]

2009/9/20 Markus Schirp said:
The current working process is a global property of the underlaying system
process.

A system Process has one currency working directory, not two, or more.

You can do your directory / filename calculations, using the absolute
directory path, without any race conditions.


Yes, I realise now I should have forced users to use absolute paths, but as
it stands there's code out in the wild with stuff like:

hook :after_build do |build|
FileUtils.cp 'README', File.join(build.build_dir, 'README')
end

So the working directory needs to be set so that 'README' can be found
correctly. Internally the tool uses absolute paths, so e.g.
`build.build_dir` is an absolute path, but code written by users is likely
to use relative paths.
 
M

Markus Schirp

Forcing the users to use absolute paths may just hides the problem.
Maybe you should expand the users "relative" paths before using them.

Or monkeypatch FileUtils, and maybe dozens ruby core classes to support
a "thread-safe" cwd.
 
R

Robert Klemme

2009/9/20 Markus Schirp said:
Forcing the users to use absolute paths may just hides the problem. Maybe
you should expand the users "relative" paths before using them.

Or monkeypatch FileUtils, and maybe dozens ruby core classes to support a
"thread-safe" cwd.

That would be an option but IMHO it would be tedious and error prone.
You can easily miss a class and introduce unwanted effects.

As far as I can see the only way to make cwd thread safe would be to
use the block form and synchronize access, i.e. one thread changes
cwd, does its work and returns cwd to the old status. For obvious
reasons this is not really a good idea. IMHO the only reasonable way
to go is to

a) use cwd only in single threaded programs or with explicit
synchronization guards
b) do not change cwd and use absolute path names, even if that means
converting user input / method arguments

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,196
Latest member
ScottChare

Latest Threads

Top