Project

General

Profile

Bug #14353

$SAFE should stay at least thread-local for compatibility

Added by Eregon (Benoit Daloze) over 2 years ago. Updated 9 months ago.

Status:
Closed
Priority:
Normal
Target version:
-
[ruby-core:84850]

Description

In #14250 $SAFE changed from a frame+thread-local variable to a process-wide global variable.

This feels wrong and breaks the most common usage of $SAFE in tests:

Thread.new {
  $SAFE = 1
  sth that should be checked to work under $SAFE==1
}.join

It is very clear this is incompatible given how many files (33!) had to be changed in r61510.
And it has wide ranging confusing side-effects, one example: https://travis-ci.org/ruby/spec/jobs/328524568

I agree frame-local is too much for $SAFE.

But removing thread-local seems to only introduce large incompatibilities.

It also makes it impossible to use it in a thread-safe way.
The common pattern (not necessarily for $SAFE, more often for $VERBOSE):

begin
  old = $SAFE
  $SAFE = 1
  something under SAFE==1
ensure
  $SAFE = old
end

is unsafe if two threads run it concurrently (The last thread executing $SAFE = old might restore to 1 even though it should be 0).

(Actually I believe most built-in variables (e.g. $VERBOSE) should be thread-local and not process-wide due to this)

Since $SAFE is being deprecated and removed, I don't see any reason to make it more incompatible than needed.

ko1 (Koichi Sasada) Can we switch it back to thread-local for compatibility, avoiding headaches and keeping it usable with multiple threads?


Related issues

Related to Ruby master - Feature #14250: Make `$SAFE` process global state and allow to set 0 againClosedko1 (Koichi Sasada)Actions
Is duplicate of Ruby master - Feature #5455: $SAFE should be removedRejectedmatz (Yukihiro Matsumoto)Actions

Also available in: Atom PDF