@@ -221,7 +221,6 @@ def initialize(basename="", tmpdir=nil, mode: 0, **options)
221
221
222
222
@unlinked = false
223
223
@mode = mode |File ::RDWR |File ::CREAT |File ::EXCL
224
- @finalizer_obj = Object . new
225
224
tmpfile = nil
226
225
::Dir ::Tmpname . create ( basename , tmpdir , **options ) do |tmpname , n , opts |
227
226
opts [ :perm ] = 0600
@@ -231,29 +230,27 @@ def initialize(basename="", tmpdir=nil, mode: 0, **options)
231
230
232
231
super ( tmpfile )
233
232
234
- define_finalizers
235
- end
236
-
237
- private def define_finalizers
238
- ObjectSpace . define_finalizer ( @finalizer_obj , Closer . new ( __getobj__ ) )
239
- ObjectSpace . define_finalizer ( @finalizer_obj , Remover . new ( __getobj__ . path ) )
233
+ @finalizer_manager = FinalizerManager . new ( __getobj__ . path )
234
+ @finalizer_manager . register ( self , __getobj__ )
240
235
end
241
236
242
237
def initialize_dup ( other ) # :nodoc:
243
238
initialize_copy_iv ( other )
244
239
super ( other )
240
+ @finalizer_manager . register ( self , __getobj__ )
245
241
end
246
242
247
243
def initialize_clone ( other ) # :nodoc:
248
244
initialize_copy_iv ( other )
249
245
super ( other )
246
+ @finalizer_manager . register ( self , __getobj__ )
250
247
end
251
248
252
249
private def initialize_copy_iv ( other ) # :nodoc:
253
250
@unlinked = other . unlinked
254
251
@mode = other . mode
255
252
@opts = other . opts
256
- @finalizer_obj = other . finalizer_obj
253
+ @finalizer_manager = other . finalizer_manager
257
254
end
258
255
259
256
# Opens or reopens the file with mode "r+".
@@ -263,8 +260,7 @@ def open
263
260
mode = @mode & ~( File ::CREAT |File ::EXCL )
264
261
__setobj__ ( File . open ( __getobj__ . path , mode , **@opts ) )
265
262
266
- ObjectSpace . undefine_finalizer ( @finalizer_obj )
267
- define_finalizers
263
+ @finalizer_manager . register ( self , __getobj__ )
268
264
269
265
__getobj__
270
266
end
@@ -334,9 +330,6 @@ def unlink
334
330
return
335
331
end
336
332
337
- ObjectSpace . undefine_finalizer ( @finalizer_obj )
338
- ObjectSpace . define_finalizer ( @finalizer_obj , Closer . new ( __getobj__ ) )
339
-
340
333
@unlinked = true
341
334
end
342
335
alias delete unlink
@@ -370,35 +363,32 @@ def inspect
370
363
371
364
protected
372
365
373
- attr_reader :unlinked , :mode , :opts , :finalizer_obj
374
-
375
- class Closer # :nodoc:
376
- def initialize ( tmpfile )
377
- @tmpfile = tmpfile
378
- end
379
-
380
- def call ( *args )
381
- @tmpfile . close
382
- end
383
- end
366
+ attr_reader :unlinked , :mode , :opts , :finalizer_manager
384
367
385
- class Remover # :nodoc:
368
+ class FinalizerManager # :nodoc:
386
369
def initialize ( path )
387
- @pid = Process . pid
370
+ @open_files = { }
388
371
@path = path
372
+ @pid = Process . pid
389
373
end
390
374
391
- def call ( *args )
392
- return if @pid != Process . pid
375
+ def register ( obj , file )
376
+ ObjectSpace . undefine_finalizer ( obj )
377
+ ObjectSpace . define_finalizer ( obj , self )
378
+ @open_files [ obj . object_id ] = file
379
+ end
393
380
394
- $stderr. puts "removing #{ @path } ..." if $DEBUG
381
+ def call ( object_id )
382
+ @open_files . delete ( object_id ) . close
395
383
396
- begin
397
- File . unlink ( @path )
398
- rescue Errno ::ENOENT
384
+ if @open_files . empty? && Process . pid == @pid
385
+ $stderr. puts "removing #{ @path } ..." if $DEBUG
386
+ begin
387
+ File . unlink ( @path )
388
+ rescue Errno ::ENOENT
389
+ end
390
+ $stderr. puts "done" if $DEBUG
399
391
end
400
-
401
- $stderr. puts "done" if $DEBUG
402
392
end
403
393
end
404
394
0 commit comments