Description
Hi,
We've monkeypatched about thread safety as follows:
def klass_name
return @klass_name if defined?(@klass_name)
@klass_name = name.scan(/(.*)Session/)[0]
@klass_name = klass_name ? klass_name[0] : nil
end
https://github.com/binarylogic/authlogic/blob/master/lib/authlogic/session/base.rb#L784
Expected Behavior
The @klass_name
will return only after we will extract the klass_name
from the array (klass_name[0]
)
Actual Behavior
When there are multiple calls to the method simultaneously in a multi-threaded context, it happens occasionally that the line:
@klass_name = name.scan(/(.*)Session/)[0]
is executed, and then the other thread reaches the line:
return @klass_name if defined?(@klass_name)
which will return the @klass_name
as the intermediate array.
So for example, if name is "UserSession", name.scan(/(.*)Session/)[0] returns ["User"], which is the value received in the other thread.
Suggested solution:
Assign @klass_name in one row will ensure that @klass_name will get value only after we will take out the value from the array.
def klass_name
return @klass_name if defined?(@klass_name)
@klass_name = name.scan(/(.*)Session/)[0]&.first
end
I'm new to OSS so I'm not comfortable submitting a patch, but I wanted to open an issue so someone can fix this for everyone.