Description:
fixed too many open file error
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r96:efe2fae6056b - - 1 file changed: 2 inserted, 0 deleted

@@ -1,107 +1,109
1 require 'ftools'
1 require 'ftools'
2
2
3 # DirInit::Manager handles directory initialization and clean-up when
3 # DirInit::Manager handles directory initialization and clean-up when
4 # there are many concurrent processes that wants to modify the
4 # there are many concurrent processes that wants to modify the
5 # directory in the same way.
5 # directory in the same way.
6 #
6 #
7 # An example usage is when each process wants to copy some temporary
7 # An example usage is when each process wants to copy some temporary
8 # files to the directory and delete these files after finishing its
8 # files to the directory and delete these files after finishing its
9 # job. Problems may occur when the first process delete the files
9 # job. Problems may occur when the first process delete the files
10 # while the second process is still using the files.
10 # while the second process is still using the files.
11 #
11 #
12 # This library maintain a reference counter on the processes using the
12 # This library maintain a reference counter on the processes using the
13 # directory. It locks the dir to manage critical section when
13 # directory. It locks the dir to manage critical section when
14 # updating the reference counter.
14 # updating the reference counter.
15
15
16 module DirInit
16 module DirInit
17
17
18 class Manager
18 class Manager
19
19
20 def initialize(dir_name, usage_filename='.usage_counter')
20 def initialize(dir_name, usage_filename='.usage_counter')
21 @dir_name = dir_name
21 @dir_name = dir_name
22 @usage_filename = usage_filename
22 @usage_filename = usage_filename
23 end
23 end
24
24
25 # Check if someone has initialized the dir. If not, call block.
25 # Check if someone has initialized the dir. If not, call block.
26
26
27 def setup # :yields: block
27 def setup # :yields: block
28 dir = File.new(@dir_name)
28 dir = File.new(@dir_name)
29 dir.flock(File::LOCK_EX)
29 dir.flock(File::LOCK_EX)
30 begin
30 begin
31 counter_filename = get_counter_filename
31 counter_filename = get_counter_filename
32 if File.exist? counter_filename
32 if File.exist? counter_filename
33 # someone is here
33 # someone is here
34 f = File.new(counter_filename,"r+")
34 f = File.new(counter_filename,"r+")
35 counter = f.read.to_i
35 counter = f.read.to_i
36 f.seek(0)
36 f.seek(0)
37 f.write("#{counter+1}\n")
37 f.write("#{counter+1}\n")
38 f.close
38 f.close
39 else
39 else
40 # i'm the first, create the counter file
40 # i'm the first, create the counter file
41 counter = 0
41 counter = 0
42 f = File.new(counter_filename,"w")
42 f = File.new(counter_filename,"w")
43 f.write("1\n")
43 f.write("1\n")
44 f.close
44 f.close
45 end
45 end
46
46
47 # if no one is here
47 # if no one is here
48 if counter == 0
48 if counter == 0
49 if block_given?
49 if block_given?
50 yield
50 yield
51 end
51 end
52 end
52 end
53
53
54 rescue
54 rescue
55 raise
55 raise
56
56
57 ensure
57 ensure
58 # make sure it unlock the directory
58 # make sure it unlock the directory
59 dir.flock(File::LOCK_UN)
59 dir.flock(File::LOCK_UN)
60 + dir.close
60 end
61 end
61 end
62 end
62
63
63 # Check if I am the last one using the dir. If true, call block.
64 # Check if I am the last one using the dir. If true, call block.
64
65
65 def teardown
66 def teardown
66 dir = File.new(@dir_name)
67 dir = File.new(@dir_name)
67 dir.flock(File::LOCK_EX)
68 dir.flock(File::LOCK_EX)
68 begin
69 begin
69 counter_filename = get_counter_filename
70 counter_filename = get_counter_filename
70 if File.exist? counter_filename
71 if File.exist? counter_filename
71 # someone is here
72 # someone is here
72 f = File.new(counter_filename,"r+")
73 f = File.new(counter_filename,"r+")
73 counter = f.read.to_i
74 counter = f.read.to_i
74 f.seek(0)
75 f.seek(0)
75 f.write("#{counter-1}\n")
76 f.write("#{counter-1}\n")
76 f.close
77 f.close
77
78
78 if counter == 1
79 if counter == 1
79 # i'm the last one
80 # i'm the last one
80
81
81 File.delete(counter_filename)
82 File.delete(counter_filename)
82 if block_given?
83 if block_given?
83 yield
84 yield
84 end
85 end
85 end
86 end
86 else
87 else
87 # This is BAD
88 # This is BAD
88 raise "Error: reference count missing"
89 raise "Error: reference count missing"
89 end
90 end
90
91
91 rescue
92 rescue
92 raise
93 raise
93
94
94 ensure
95 ensure
95 # make sure it unlock the directory
96 # make sure it unlock the directory
96 dir.flock(File::LOCK_UN)
97 dir.flock(File::LOCK_UN)
98 + dir.close
97 end
99 end
98 end
100 end
99
101
100 protected
102 protected
101
103
102 def get_counter_filename
104 def get_counter_filename
103 return File.join(@dir_name,@usage_filename)
105 return File.join(@dir_name,@usage_filename)
104 end
106 end
105
107
106 end
108 end
107 end
109 end
You need to be logged in to leave comments. Login now