Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this use of threadvar threadsafe?

I've got a singleton that can be called by multiple threads.
I do some lookup of data pretty often and I what to cache the data so that I don't have to repeat the same lookup again and again.

I'd like to do something akin to using static local variables, but in a thread-safe way. I suspect the code below is watertight. Is this correct?

type
  TPrevious = record
  public
    Fontname: string;
    FontSize: integer;
    Canvas: pointer;
    Width: integer;
  end;

threadvar Previous: TPrevious;

function TEditorOptions.GetEditorFontWidth(const Canvas: TCanvas): integer;
var
  Font: TFont;
//var  //static vars            <<-- static var != threadsafe
//  PreviousFontName: string = '';
//  PreviousFontSize: integer = 0;
//  PreviousCanvas: pointer = nil;
//  PreviousWidth: integer = 0;
begin
  {1: I'm assuming a managed threadvar is always initialized to Default(T)}
  if (Previous.Fontname <> '') then begin
      //Cache the values, so we don't recalculate all the time.
      //Caching is per thread, but that's fine.
    if (SameText(Previous.FontName, FFontName)) and (Previous.FontSize = FFontSize)
       and (pointer(Canvas) = Previous.Canvas) then Exit(Previous.Width);
  end;
  Previous.Canvas := pointer(Canvas);
  Previous.FontName := FFontName;
  Previous.FontSize := FFontSize;
  Result:= SomeCalculation(Canvas, FFontName, FFontSize);
  ....
    Previous.Width:= Result;
  ....
end;

I have 2 questions:

A: Am I correct in assuming that managed threadvars like the string FontName are always initialized to Default(T) (i.e. '')

B: Is this code fully threadsafe/ re-entrant?

like image 833
Johan Avatar asked May 14 '17 19:05

Johan


People also ask

What do you mean by Threadsafe?

Thread safety is a computer programming concept applicable to multi-threaded code. Thread-safe code only manipulates shared data structures in a manner that ensures that all threads behave properly and fulfill their design specifications without unintended interaction.

Is static variable thread safe in Java?

Thread SafetyStatic variables are not thread safe. Instance variables do not require thread synchronization unless shared among threads. But, static variables are always shared by all the threads in the process. Hence, access to static variable is not thread safe.

How do you make an instance variable thread safe in Java?

Given the structure of the JVM, local variables, method parameters, and return values are inherently "thread-safe." But instance variables and class variables will only be thread-safe if you design your class appropriately. As an example of a class that is not thread-safe, consider the RGBColor class, shown below.

Are method local variables thread safe?

On its stack(basically thread stack), local primitives and local reference variables are stored. Hence one thread does not share its local variables with any other thread as these local variables and references are inside the thread's private stack. Hence local variables are always thread-safe.


1 Answers

  1. Any threadvar instance is filled with zero, so your string variable is properly initialized.

  2. Sadly, threadvar do not handle the memory of their managed type... As a result, you need to release each string inside your Previous variable.

  3. In practice, I do not store managed types in threadvar, but use another pattern (like injection at constructor level).

  4. Small performance hit: access to each Previous.xxxxx member has a performance cost: you may rather fill a local variable pointer with @Previous, then use this pointer to access the fields (or use with Previous do - but this syntax may be confusing).

like image 189
Arnaud Bouchez Avatar answered Nov 05 '22 21:11

Arnaud Bouchez