library GlobalData; uses Windows, GlobalHdr in 'GlobalHdr.pas'; const GlobalMutexName = 'MCHGlobalMutex - BBARAgAGBQI4r8mOAAoJEPwzBQsIT9FngEA'; GlobalMapName = 'MCHGlobalMap - AJ9Qfi3m4vqgUhKYA7qBfzrMDbkpbQtTWFy'; type TLocalInfo = record LocalThreads: integer; end; TSyncHandles = record LocalSection: TRTLCriticalSection; GlobalMutex: THandle; end; PGlobalInfo = ^TGlobalInfo; TGlobalHandles = record FileMapping: THandle; GlobalInfo: PGlobalInfo; end; var SyncHandles: TSyncHandles; LocalInfo: TLocalInfo; GlobalHandles: TGlobalHandles; procedure ReadInfo(var GlobalInfo: TGlobalInfo; var LocalThreads: integer); stdcall; begin WaitForSingleObject(SyncHandles.GlobalMutex, INFINITE); EnterCriticalSection(SyncHandles.LocalSection); GlobalInfo := GlobalHandles.GlobalInfo^; LocalThreads := LocalInfo.LocalThreads; LeaveCriticalSection(SyncHandles.LocalSection); ReleaseMutex(SyncHandles.GlobalMutex); end; procedure SetSharedInteger(NewValue: integer); stdcall; begin WaitForSingleObject(SyncHandles.GlobalMutex, INFINITE); GlobalHandles.GlobalInfo.SharedNumber := NewValue; ReleaseMutex(SyncHandles.GlobalMutex); end; procedure IncSharedInteger; stdcall; begin WaitForSingleObject(SyncHandles.GlobalMutex, INFINITE); Inc(GlobalHandles.GlobalInfo.SharedNumber); ReleaseMutex(SyncHandles.GlobalMutex); end; procedure DecSharedInteger; stdcall; begin WaitForSingleObject(SyncHandles.GlobalMutex, INFINITE); Dec(GlobalHandles.GlobalInfo.SharedNumber); ReleaseMutex(SyncHandles.GlobalMutex); end; function AtomicIncThreadCount: integer; {returns number of local threads for Delphi Memory Manager} begin WaitForSingleObject(SyncHandles.GlobalMutex, INFINITE); EnterCriticalSection(SyncHandles.LocalSection); Inc(GlobalHandles.GlobalInfo.GlobalThreads); Inc(LocalInfo.LocalThreads); result := LocalInfo.LocalThreads; LeaveCriticalSection(SyncHandles.LocalSection); ReleaseMutex(SyncHandles.GlobalMutex); end; procedure AtomicDecThreadCount; begin WaitForSingleObject(SyncHandles.GlobalMutex, INFINITE); EnterCriticalSection(SyncHandles.LocalSection); Dec(GlobalHandles.GlobalInfo.GlobalThreads); Dec(LocalInfo.LocalThreads); LeaveCriticalSection(SyncHandles.LocalSection); ReleaseMutex(SyncHandles.GlobalMutex); end; procedure AtomicIncProcessCount; begin WaitForSingleObject(SyncHandles.GlobalMutex, INFINITE); Inc(GlobalHandles.GlobalInfo.GlobalProcesses); ReleaseMutex(SyncHandles.GlobalMutex); end; procedure AtomicDecProcessCount; begin WaitForSingleObject(SyncHandles.GlobalMutex, INFINITE); Dec(GlobalHandles.GlobalInfo.GlobalProcesses); ReleaseMutex(SyncHandles.GlobalMutex); end; procedure SetupSynchronisation; begin with SyncHandles do begin InitializeCriticalSection(LocalSection); GlobalMutex := CreateMutex(nil, false, GlobalMutexName); Assert(GlobalMutex <> INVALID_HANDLE_VALUE); end; end; procedure CloseSynchronisation; begin with SyncHandles do begin DeleteCriticalSection(LocalSection); CloseHandle(GlobalMutex); end; end; procedure SetupGlobalInfo; var FirstCaller: boolean; begin with GlobalHandles do begin WaitForSingleObject(SyncHandles.GlobalMutex, INFINITE); FileMapping := CreateFileMapping(High(Cardinal), nil, PAGE_READWRITE, 0, sizeof(TGlobalInfo), GlobalMapName); Assert(FileMapping <> INVALID_HANDLE_VALUE); FirstCaller := GetLastError <> ERROR_ALREADY_EXISTS; GlobalInfo := MapViewOfFile(FileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); Assert(GlobalInfo <> nil); if FirstCaller then FillMemory(GlobalInfo, sizeof(TGlobalInfo), 0); ReleaseMutex(SyncHandles.GlobalMutex); end; end; procedure CloseGlobalInfo; begin with GlobalHandles do begin UnmapViewOfFile(GlobalInfo); CloseHandle(FileMapping); end; end; procedure DLLFinalisation; begin AtomicDecThreadCount; AtomicDecProcessCount; CloseGlobalInfo; CloseSynchronisation; end; procedure EntryPoint(Reason: integer); begin case Reason of DLL_THREAD_ATTACH: if AtomicIncThreadCount > 1 then IsMultiThread := true; DLL_THREAD_DETACH: AtomicDecThreadCount; DLL_PROCESS_DETACH: DLLFinalisation; else Assert(false); end; end; exports ReadInfo, SetSharedInteger, IncSharedInteger, DecSharedInteger; begin SetupSynchronisation; SetupGlobalInfo; AtomicIncProcessCount; AtomicIncThreadCount; DLLProc := @EntryPoint; end.