рдХрд┐рд╕реА рднреА рдзрд╛рдЧреЗ рдХреЗ рдереНрд░реЗрдб рд▓реЛрдХрд▓ рд╕реНрдЯреЛрд░реЗрдЬ (TLS) рд╡реИрд░рд┐рдПрдмрд▓ рддрдХ рдкрд╣реБрдВрдЪ

рдпрд╣ рд▓реЗрдЦ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рдбреЗрд▓реНрдлреА рдореЗрдВ рдереНрд░реЗрдб рд▓реЛрдХрд▓ рд╕реНрдЯреЛрд░реЗрдЬ рдмреНрд▓реЙрдХ рд╕реЗ рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдПред рд╣рд╛рд▓рд╛рдВрдХрд┐, "рд╡рд┐рджреЗрд╢реА" рдЯреАрдПрд▓рдПрд╕ рдмреНрд▓реЙрдХ рдЦреЛрдЬрдиреЗ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рд╕рднреА рд╡рд┐рдВрдбреЛрдЬ рдХрдВрдкрд╛рдЗрд▓рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рд╣реИрдВ рдФрд░ рдХрд┐рд╕реА рднреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддреЗ рд╣реИрдВ рдЬреЛ рдЯреАрдПрд▓рдПрд╕ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕ рд░реВрдк рдореЗрдВ рд╡рд┐рдВрдбреЛрдЬ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред

рдбреЗрд▓реНрдлреА рдореЗрдВ, рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдереНрд░реЗрдбрд╡рд╛рд░ рдмреНрд▓реЙрдХ рдореЗрдВ рдШреЛрд╖рд┐рдд рдЪрд░ рд╕реНрд╡рддрдВрддреНрд░ рдорд╛рдиреЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЗ рд╕рд╛рде рдкреНрд░рддреНрдпреЗрдХ рдереНрд░реЗрдб рдХреЗ рд▓рд┐рдП рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рд╕реНрдЯреНрд░реАрдо рдореВрд▓реНрдпреЛрдВ рдХреА рдЕрдкрдиреА рдкреНрд░рддрд┐ рдкрдврд╝рддрд╛ рдФрд░ рд▓рд┐рдЦрддрд╛ рд╣реИред
рд▓реЗрдХрд┐рди рдХрднреА-рдХрднреА рджреВрд╕рд░реЗ рдереНрд░реЗрдб рдХреЗ рдЕрдиреБрд░реВрдк рдЪрд░ рдХреЛ рдкрдврд╝рдирд╛ рдпрд╛ рдмрджрд▓рдирд╛ рднреА рдЖрд╡рд╢реНрдпрдХ рд╣реЛрддрд╛ рд╣реИред
рдмреЗрд╢рдХ, рдРрд╕реА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рдмрджрд▓рдирд╛ рдмреЗрд╣рддрд░ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдПрдХ рд╕рдорд╛рдзрд╛рди рд╣реИред
рд╕рднреА рдбреЗрдЯрд╛ рдмреНрд▓реЙрдХ (рдереНрд░реЗрдб рд▓реЛрдХрд▓ рд╕реНрдЯреЛрд░реЗрдЬ, рдЯреАрдПрд▓рдПрд╕) рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдореЗрдореЛрд░реА рдореЗрдВ рд╣реЛрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкрддреЗ рдкрд░, рдкреНрд░рддреНрдпреЗрдХ рдереНрд░реЗрдб рдЕрдкрдиреЗ рдореЗрдореЛрд░реА рдПрд░рд┐рдпрд╛ рдореЗрдВ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдПрдХ рд╡реИрд░рд┐рдПрдмрд▓ рдмреНрд▓реЙрдХ рдФрд░ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдорд╛рди рдХреЛ рдЦреЛрдЬрдирд╛ рд╕рдВрднрд╡ рд╣реИ рдЬреЛ рдореМрдЬреВрджрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рднреАрддрд░ рдмрдиреЗ рдХрд┐рд╕реА рднреА рдереНрд░реЗрдб рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛред

рдереНрд░реЗрдб рд╕реНрдерд╛рдиреАрдп рд╕рдВрдЧреНрд░рд╣рдг рдХреНрд╖реЗрддреНрд░ рдЬрд┐рд╕рдореЗрдВ рдорд╛рди рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВ, TEB рдбреЗрдЯрд╛ рдмреНрд▓реЙрдХ рд╕реЗ рдорд╛рди рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕рд░рдгреА рдХрд╛ рдкрддрд╛ рдСрдлрд╕реЗрдЯ tlsArray рдкрд░ рд╣реИ (SysInit.pas рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдШреЛрд╖рд┐рдд)ред
рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рд░ рдЬрдм рдереНрд░реЗрдб рдХреЛ рдпрд╛рд░реНрди рдХреЗ рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ _GetTls рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рд╡рд░реНрддрдорд╛рди рдереНрд░реЗрдб рдХреЗ рдбреЗрдЯрд╛ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЙрдЗрдВрдЯрд░ рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдПрдХ рдЪрд░ рдСрдлрд╕реЗрдЯ рдЬреЛрдбрд╝рдХрд░, рдЖрдк рдЗрд╕рдХрд╛ рдкрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рджреВрд╕рд░реЗ рдзрд╛рдЧреЗ рд╕реЗ рдПрдХ рдЪрд░ рдХрд╛ рдкрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╡рд░реНрддрдорд╛рди рдмреНрд▓реЙрдХ рдХреЗ рдкрддреЗ рдХреЛ рдШрдЯрд╛рдПрдВ рдФрд░ рд▓рдХреНрд╖реНрдп рдзрд╛рдЧреЗ рдХреЗ рдмреНрд▓реЙрдХ рдХрд╛ рдкрддрд╛ рдЬреЛрдбрд╝реЗрдВред
_GetTls рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдХреЗрд╡рд▓ рдЕрд╕рдВрднрд╡ рд╣реИ; рдЖрдкрдХреЛ рдирд╛рдо рдФрд░ рд╕рд┐рд╕реНрдЯрдо рдореЙрдбреНрдпреВрд▓ рдХреЗ рдирд╛рдо рдХреЗ рд╕рд╛рдордиреЗ @ рдкреНрд░рддреАрдХ рдЬреЛрдбрд╝рдХрд░ рдХреЛрдбрд╛рдВрддрд░рдХ рдХреЛрдб рд╕реЗ рдЗрд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

function GetCurrentTls: Pointer; asm call System.@GetTls end; 


рдЕрдзрд┐рдХрд╛рдВрд╢ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд╣реА рд╡рд┐рдзрд┐ рдЙрдкрдпреБрдХреНрдд рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдирд╛рдо рдЕрдВрдбрд░рд╕реНрдХреЛрд░ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдбреЗрд▓реНрдлреА рдХреЛрдб рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдирд╣реАрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ:

 call System.@ 


рд╢реБрд░реБрдЖрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣ рд╕реЗ рдПрдХ рдлрдВрдХреНрд╢рди рд▓рд┐рдЦреЗрдВ:

 function GetTlsAddress( hThread: THandle; Addr: Pointer ): Pointer; var Offset: NativeInt; begin Offset := ( PByte( Addr ) - PByte( GetCurrentTls ) ); Result := (?) + Offset; end; 


рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдереНрд░реЗрдб рдХреА рдПрдХ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдирд╣реАрдВ)! рд╣рдореЗрдВ рдереНрд░реЗрдб рд╡реИрд░рд┐рдПрдмрд▓реНрд╕ рдХреЗ рд╡рд░реНрддрдорд╛рди рдмреНрд▓реЙрдХ рдореЗрдВ рд╡реЗрд░рд┐рдПрдмрд▓ рдХреА рдЬрд░реВрд░рдд рд╣реЛрддреА рд╣реИред рдлрд╝рдВрдХреНрд╢рди рдЙрд╕реА рдЪрд░ рдХрд╛ рдкрддрд╛ рд▓реМрдЯрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рдЕрдиреНрдп рдереНрд░реЗрдб рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред

рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐ рдореЗрдВ, рд╣рдореЗрдВ рдЯреАрдПрд▓рдПрд╕ рдмреНрд▓реЙрдХ рдХреА рд╢реБрд░реБрдЖрдд рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдЪрд░ рдХреА рднрд░рдкрд╛рдИ рдорд┐рд▓реАред
рдЕрдм рд╣рдореЗрдВ рдЗрд╕ рдСрдлрд╕реЗрдЯ рдХреЛ рд▓рдХреНрд╖реНрдп рдереНрд░реЗрдб рдХреЗ рд╕реНрдерд╛рдиреАрдп рдЪрд░ рдХреЗ рд╕реВрдЪрдХ рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬреЛ TEB рдбреЗрдЯрд╛ рдмреНрд▓реЙрдХ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИред

рдЯреАрдПрдЪрдмреА рдереНрд░реЗрдб рдХреА рдСрдлрд╕реЗрдЯ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдЖрднрд╛рд╕реА рд╕реНрдерд╛рди рдореЗрдВ NtQueryInformationThread рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рд╡рд┐рдВрдбреЛрдЬ рдиреЗрдЯрд┐рд╡ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ рдЬреЛ ntdll.dll рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рд╣реИред
рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк JEDI Win32 рдПрдкреАрдЖрдИ рд╕реЗрдЯ рд╕реЗ JwaNative.pas рдореЙрдбреНрдпреВрд▓ рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдмрд╛рд╣рд░реА рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЗ рд╕рд╛рде рдмрд╛рд╣рд░реА рдлрд╝рдВрдХреНрд╢рди рдШреЛрд╖рдгрд╛ рдХреЛ рд╕реАрдзреЗ рд╡рд░реНрддрдорд╛рди рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ (рдЖрдкрдХреЛ рдорд╛рдирдХ Windows.pas рдореЙрдбреНрдпреВрд▓ рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ):

 type THREAD_BASIC_INFORMATION = record ExitStatus: ULONG{NTSTATUS}; TebBaseAddress: Pointer{PNT_TIB}; {ClientId: ; //  ,      AffinityMask: ; //   ,      Priority: ; //  .        TebBaseAddress BasePriority: ;} end; function NtQueryInformationThread( ThreadHandle : THandle; ThreadInformationClass : ULONG {THREADINFOCLASS}; ThreadInformation : PVOID; ThreadInformationLength : ULONG; ReturnLength : PULONG ): ULONG; stdcall; external 'ntdll.dll'; 


TEB рдкрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде, рдлрд╝рдВрдХреНрд╢рди рдЕрдм рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:

 function GetTlsAddress( hThread: THandle; Addr: Pointer ): Pointer; var basic: THREAD_BASIC_INFORMATION; Len: ULONG; Offset: NativeInt; begin NtQueryInformationThread( hThread, 0{ThreadBasicInformation}, @basic, SizeOf( basic ), @Len ); Offset := ( PByte( Addr ) - PByte( GetCurrentTls ) ); Result := (?) + Offset; end; 


рдЕрдм рдпрд╣ PEB рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ TLS рдмреНрд▓реЙрдХ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИред рд╣рдо SysInit рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ _GetTls рдлрд╝рдВрдХреНрд╢рдиред

32-рдмрд┐рдЯ OS рдореЗрдВ, TLS рд╕рд░рдгреА рдХрд╛ рдкрддрд╛ (рдЬрд┐рд╕рдореЗрдВ TlsIndex рдЗрдВрдбреЗрдХреНрд╕ рдереНрд░реЗрдб рдбреЗрдЯрд╛ рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдкрддрд╛ рд╣реИ) рдХрд╛ рдкрддрд╛ рдЗрд╕ рдХреЛрдб рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

  MOV EAX,TlsIndex MOV EDX,FS:[tlsArray] MOV EAX,[EDX+EAX*4] 


рдЗрд╕ рддрд░рд╣ 64-рдмрд┐рдЯ рдХреЗ рд▓рд┐рдП:

  P := PPPointerArray(PByte(@GSSegBase) + tlsArray)^; Result := P^[TlsIndex]; 


рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЬрд╛рдБрдЪ рджрд┐рдЦрд╛ рд╕рдХрддреА рд╣реИ рдХрд┐ 64-рдмрд┐рдЯ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдХреЛрдб 32-рдмрд┐рдЯ рдореЗрдВ рднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЕрдЧрд░ рд╣рдо рдЕрд▓рдЧ-рдЕрд▓рдЧ tlsArray рдорд╛рди рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рднреА рдХрд┐ TEB GS рдкрд░ рд╕реНрдерд┐рдд рд╣реИ: [0], FS рдирд╣реАрдВ [0] рдЬреИрд╕рд╛ рдХрд┐ 32-рдмрд┐рдЯ рд╡рд┐рдВрдбреЛрдЬ рдореЗрдВ рд╣реИред

рдЪреВрдБрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ TEB рдПрдбреНрд░реЗрд╕ (рдмреЗрд╕рд┐рдХ рд╕реНрдЯреНрд░рдХреНрдЪрд░ рд╕реЗ TebBaseAddress рдлреАрд▓реНрдб) рд╣реИ, рдЬреЛ Win64 рдХреЗ рд▓рд┐рдП GS рд╕реЗрдЧрдореЗрдВрдЯ рдХреА рд╢реБрд░реБрдЖрдд рдФрд░ Win32 рдХреЗ рд▓рд┐рдП FS рд╕реЗрдЧрдореЗрдВрдЯ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ, рд╣рдо TEG рдкреЙрдЗрдВрдЯрд░ рдХреЗ рд╕рд╛рде @GSSegBase рдорд╛рди рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╣рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖ рдерд╛

  Tls := PPPointerArray( PByte( basic.TebBaseAddress ) + tlsArray )^; 


рдХреБрдЫ рдЕрдиреБрдХреВрд▓рди рдХреЗ рд╕рд╛рде рдПрдХ рдкреВрд░реНрдг рдХрд╛рд░реНрдп рдЗрд╕ рддрд░рд╣ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ:

 function GetTlsAddress( hThread: THandle; Addr: Pointer ): Pointer; var basic: THREAD_BASIC_INFORMATION; Len: ULONG; Tls: PPointerArray; begin if hThread = GetCurrentThread then Exit( Addr ); NtQueryInformationThread( hThread, 0{ThreadBasicInformation}, @basic, SizeOf( basic ), @Len ); Tls := PPPointerArray( PByte( basic.TebBaseAddress ) + tlsArray )^; Result := PByte( Tls^[TlsIndex] ) + ( PByte( Addr ) - PByte( GetCurrentTls ) ); end; 


рдХреЛрдб рдореЗрдВ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рдХрдИ рд╕реНрдерд┐рд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд░реНрдЧ рдмрдирд╛рдПрдВрдЧреЗ:

 type TThreadLocalStorage = class private class function GetTlsAddress( hThread: THandle; Addr: Pointer ): Pointer; static; public class function GetThreadVar<T>( hThread: THandle; var TlsVar: T ): T; static; class procedure SetThreadVar<T>( hThread: THandle; var TlsVar: T; const Value: T ); static; class property Tls[hThread: THandle; Addr: Pointer]: Pointer read GetTlsAddress; end; 


рддрдм рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреЛ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 class function TThreadLocalStorage.GetThreadVar<T>( hThread: THandle; var TlsVar: T ): T; begin Result := T( GetTlsAddress( hThread, @TlsVar )^ ); end; class procedure TThreadLocalStorage.SetThreadVar<T>( hThread: THandle; var TlsVar: T; const Value: T ); begin T( GetTlsAddress( hThread, @TlsVar )^ ) := Value; end; 


рдкреИрд░рд╛рдореАрдЯрд░ рдХрд┐рдП рдЧрдП рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЯреА рдХреЛ рдкреЙрдЗрдВрдЯрд░ рдШреЛрд╖рд┐рдд рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИред
рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЖрдк рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 X := T(PointerVar^); T(PointerVar^) := X; 


рдбреЗрд▓реНрдлреА рдПрдХ рдЕрдкреНрд░рдХрд╛рд╢рд┐рдд рдкреЙрдЗрдВрдЯрд░ рдХреА рдбреЗрд░реЗрдлреЗрд░рд┐рдВрдЧ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдпрджрд┐ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд░реВрдкрд╛рдВрддрд░рдг рддреБрд░рдВрдд рд╣реЛрддрд╛ рд╣реИ рдпрд╛ рдпрджрд┐ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд┐рдирд╛ рдРрд╕рд╛ рдорд╛рди рдлрд┐рд▓реНрдХрд╛рд░ рдФрд░ рдореВрд╡ рдЬреИрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЬрд┐рд╕рдореЗрдВ рддрд░реНрдХ рднреА рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд┐рдирд╛ рдШреЛрд╖рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ)ред

рдЕрдм, "рд╡рд┐рджреЗрд╢реА" рдзрд╛рдЧреЗ рдХреЗ рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 threadvar TlsX; ... TThreadLocalStorage.GetThreadVar<Integer>( Thrd, TlsX ); 


рдФрд░ TThreadLocalStorage рд╡рд░реНрдЧ рдХреЗ рдмрд╛рдж рдРрд╕реА рдШреЛрд╖рдгрд╛ рдХреЛ рдЬреЛрдбрд╝рдирд╛:

 type TLS = TThreadLocalStorage; 


рдЖрдк рдХреЛрдб рдХреЛ рдЫреЛрдЯрд╛ рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
  X := TLS.GetThreadVar<Integer>( Thrd, TlsX ); 


рдирд┐рд╖реНрдХрд░реНрд╖ рдореЗрдВ, рдпрд╣ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХрд┐рд╕реА рдЕрдиреНрдп рдзрд╛рдЧреЗ рд╕реЗ рдПрдХ рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдХрд┐рд╕реА рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдпрд╛рдж рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреИрд╕реЗ рдХрд┐ рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рддрдХ рдкрд╣реБрдВрдЪрдирд╛ рдЬреЛ рд╕рднреА рдереНрд░реЗрдбреНрд╕ рддрдХ рдкрд╣реБрдВрдЪ рдпреЛрдЧреНрдп рд╣реИрдВред рдпрд╣ рдЗрдВрдХ, рдбреЗрд╕ рдСрдкрд░реЗрд╢рдВрд╕ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдХрдВрдкреЛрдЬрд┐рдЯ рдбреЗрдЯрд╛ рдЯрд╛рдЗрдк рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕рдЪ рд╣реИред рдереНрд░реЗрдбрд╡рд╛рд░ рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдВрдЪ рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреА рдХрдореА рдХреЗрд╡рд▓ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдереА рдХрд┐ рдЕрдиреНрдп рд╕рднреА рдереНрд░реЗрдбреНрд╕ рдореЗрдВ рд╡рд░реНрддрдорд╛рди рдереНрд░реЗрдб рдХреЗ рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдВрдЪ рдирд╣реАрдВ рд╣реИред

Source: https://habr.com/ru/post/In157783/


All Articles