-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMaxLogic.ComGuard.pas
More file actions
52 lines (42 loc) · 1.05 KB
/
Copy pathMaxLogic.ComGuard.pas
File metadata and controls
52 lines (42 loc) · 1.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
unit MaxLogic.ComGuard;
interface
type
/// <summary>
/// Ensures COM is initialised *once* per thread and automatically
/// uninitialised on thread shutdown (even in thread-pool workers).
/// </summary>
TComGuard = record
public
class procedure Ensure; static;
end;
implementation
uses
Winapi.ActiveX, System.SysUtils;
threadvar
_GuardCookie: IInterface; // lives in TLS: one copy per thread
type
TUninit = class(TInterfacedObject)
public
destructor Destroy; override;
end;
destructor TUninit.Destroy;
begin
CoUninitialize;
inherited;
end;
class procedure TComGuard.Ensure;
var
hr: HRESULT;
begin
if Assigned(_GuardCookie) then
Exit; // this thread is already COM-ready
hr := CoInitializeEx(nil, COINIT_MULTITHREADED);
case hr of
S_OK, S_FALSE: _GuardCookie := TUninit.Create; // balance with CoUninitialize
{RPC_E_CHANGED_MODE:
raise Exception.Create('Thread already initialised with a different COM apartment model');
else
OleCheck(hr); // re-raise any other failure}
end;
end;
end.