lasarus_compotents/gecko/nsThreadUtils.pas

274 lines
8.9 KiB
ObjectPascal

unit nsThreadUtils;
{$MACRO on}
{$IFDEF Windows}
{$DEFINE extdecl:=stdcall}
{$ELSE Windows}
{$DEFINE extdecl:=cdecl}
{$ENDIF}
interface
uses
nsXPCOM, nsTypes, nsGeckoStrings;
type
nsIEnvironment = interface;
nsIEventTarget = interface;
nsIProcess = interface;
nsIRunnable = interface;
nsISupportsPriority = interface;
nsIThread = interface;
nsIThreadInternal = interface;
nsIThreadObserver = interface;
nsIThreadEventFilter = interface;
nsIThreadManager = interface;
nsIThreadPoolListener = interface;
nsIThreadPool = interface;
nsITimer = interface;
nsIEnvironment = interface(nsISupports)
['{101d5941-d820-4e85-a266-9a3469940807}']
procedure _set(aName: nsAString; aValue: nsAString); safecall;
procedure get(aName: nsAString; aResult: nsAString); safecall;
function exists(aName: nsAString): PRBool; safecall;
end;
nsIEventTarget = interface(nsISupports)
['{4e8febe4-6631-49dc-8ac9-308c1cb9b09c}']
procedure dispatch(event: nsIRunnable; flags: PRUint32); safecall;
function isOnCurrentThread(): PRBool; safecall;
end;
nsIProcess = interface(nsISupports)
['{9da0b650-d07e-4617-a18a-250035572ac8}']
procedure init(aExecutable: nsIFile); safecall;
procedure initWithPid(aPid: PRUint32); safecall;
procedure kill(); safecall;
function run(aBlocking: PRBool; aArgs: PAnsiCharArray; aCount: PRUint32): PRUint32; safecall;
function getLocation(): nsIFile; safecall;
property location: nsIFile read getLocation;
function getPid(): PRUint32; safecall;
property pid: PRUint32 read getPid;
function getProcessName(): PAnsiChar; safecall;
property processName: PAnsiChar read getProcessName;
function getProcessSignature: PRUint32; safecall;
property processSignature: PRUint32 read getProcessSignature;
function getExitValue: PRInt32; safecall;
property exitValue: PRInt32 read getExitValue;
end;
nsIRunnable = interface(nsISupports)
['{4a2abaf0-6886-11d3-9382-00104ba0fd40}']
procedure run(); safecall;
end;
nsISupportsPriority = interface(nsISupports)
['{aa578b44-abd5-4c19-8b14-36d4de6fdc36}']
function getPriority: PRInt32; safecall;
procedure setPriority(aValue: PRInt32); safecall;
property priority: PRInt32 read getPriority write setPriority;
procedure adjustPriority(aDelta: PRInt32); safecall;
end;
nsIThread = interface(nsIEventTarget)
['{9c889946-a73a-4af3-ae9a-ea64f7d4e3ca}']
function getPRThread: Pointer; safecall;
property PRThread: Pointer read getPRThread;
procedure shutdown(); safecall;
function hasPendingEvents(): PRBool; safecall;
function processNextEvent(mayWait: PRBool): PRBool; safecall;
end;
nsIThreadInternal = interface(nsISupports)
['{f89b5063-b06d-42f8-bf23-4dfcf2d80d6a}']
function getObserver: nsIThreadObserver; safecall;
procedure setObserver(aValue: nsIThreadObserver); safecall;
property observer: nsIThreadObserver read getObserver write setObserver;
procedure pushEventQueue(aFilter: nsIThreadEventFilter); safecall;
procedure popEventQueue(); safecall;
end;
nsIThreadObserver = interface(nsISupports)
['{81D0B509-F198-4417-8020-08EB4271491F}']
procedure onDispatchedEvent(aThread: nsIThreadInternal); safecall;
procedure onProcessNextEvent(aThread: nsIThreadInternal; aMayWait: PRBool; aRecursionDepth: PRUint32); safecall;
procedure afterProcessNextEvent(aThread: nsIThreadInternal; aRecursionDepth: PRUint32); safecall;
end;
nsIThreadEventFilter = interface(nsISupports)
['{a0605c0b-17f5-4681-b8cd-a1cd75d42559}']
function acceptEvent(aEvent: nsIRunnable): PRBool; extdecl;
end;
nsIThreadManager = interface(nsISupports)
['{056216f5-8803-46b4-9199-d95bc1f0446f}']
function newThread(creationFlag: PRUint32): nsIThread; safecall;
function getThreadFromPRThread(prthread: Pointer): nsIThread; safecall;
function getMainThread(): nsIThread; safecall;
property mainThread: nsIThread read getMainThread;
function getCurrentThread: nsIThread; safecall;
property currentThread: nsIThread read getCurrentThread;
function getIsMainThread: PRBool; safecall;
property isMainThread: PRbool read getIsMainThread;
end;
nsIThreadPoolListener = interface(nsISupports)
['{ef194cab-3f86-4b61-b132-e5e96a79e5d1}']
procedure onThreadCreated(); safecall;
procedure onThreadShuttingDown(); safecall;
end;
nsIThreadPool = interface(nsIEventTarget)
['{394c29f0-225f-487f-86d3-4c259da76cab}']
procedure shutdown(); safecall;
function getThreadLimit(): PRUint32; safecall;
procedure setThreadLimit(aValue: PRUint32); safecall;
property threadLimit: PRUint32 read getThreadLimit write setThreadLimit;
function getIdleThreadLimit(): PRUint32; safecall;
procedure setIdleThreadLimit(aValue: PRUint32); safecall;
property idleThreadLimit: PRUint32 read getIdleThreadLimit write setIdleThreadLimit;
function getIdleThreadTimeout(): PRUint32; safecall;
procedure setIdleThreadTimeout(aValue: PRUint32); safecall;
property idleThreadTimeout: PRUint32 read getIdleThreadTimeout write setIdleThreadTimeout;
function getListener: nsIThreadPoolListener; safecall;
procedure setListener(aValue: nsIThreadPoolListener); safecall;
property listener: nsIThreadPoolListener read getListener write setListener;
end;
nsITimer = interface(nsISupports)
['{a796816d-7d47-4348-9ab8-c7aeb3216a7d}']
procedure notify(aTimer: nsITimer); safecall;
end;
const
NS_IEVENTTARGET_DISPATCH_NORMAL = 0;
NS_IEVENTTARGET_DISPATCH_SYNC = 1;
NS_ISUPPORTSPRIORITY_PRIORITY_HIGHEST = -20;
NS_ISUPPORTSPRIORITY_PRIORITY_HIGH = -10;
NS_ISUPPORTSPRIORITY_PRIORITY_NORMAL = 0;
NS_ISUPPORTSPRIORITY_PRIORITY_LOW = 10;
NS_ISUPPORTSPRIORITY_PRIORITY_LOWEST = 20;
const
NS_THREADMANAGER_CONTRACTID = '@mozilla.org/thread-manager;1';
NS_DISPATCH_NORMAL = NS_IEVENTTARGET_DISPATCH_NORMAL;
NS_DISPATCH_SYNC = NS_IEVENTTARGET_DISPATCH_SYNC;
type
nsTimerCallbackFunc = procedure (aTimer: nsITimer; aClosure: Pointer); cdecl;
function NS_NewThread(aInitialEvent: nsIRunnable = nil): nsIThread;
function NS_GetCurrentThread(): nsIThread;
function NS_GetMainThread(): nsIThread;
function NS_IsMainThread(): PRBool;
procedure NS_DispatchToCurrentThread(aEvent: nsIRunnable);
procedure NS_DispatchToMainThread(aEvent: nsIRunnable;
aDispatchFlags: PRUint32 = NS_DISPATCH_NORMAL);
procedure NS_ProcessPendingEvents(aThread: nsIThread;
aTimeout: PRUint32 = $ffffffff);
// const PR_INTERVAL_NO_TIMEOUT = $ffffffff;
function NS_HasPendingEvents(aThread: nsIThread = nil): PRBool;
function NS_ProcessNextEvent(aThread: nsIThread = nil;
aMayWait: PRBool = True): PRBool;
implementation
uses
nsXPCOMGlue, nsError, mmsystem;
function NS_NewThread(aInitialEvent: nsIRunnable): nsIThread;
var
tm: nsIThreadManager;
thread: nsIThread;
begin
NS_GetService(NS_THREADMANAGER_CONTRACTID, nsIThreadManager, tm);
thread := tm.newThread(0);
if Assigned(aInitialEvent) then
thread.dispatch(aInitialEvent, NS_DISPATCH_NORMAL);
Result := thread;
end;
function NS_GetCurrentThread(): nsIThread;
var
tm: nsIThreadManager;
begin
NS_GetService(NS_THREADMANAGER_CONTRACTID, nsIThreadManager, tm);
Result := tm.currentThread;
end;
function NS_GetMainThread(): nsIThread;
var
tm: nsIThreadManager;
begin
NS_GetService(NS_THREADMANAGER_CONTRACTID, nsIThreadManager, tm);
Result := tm.mainThread;
end;
function NS_IsMainThread(): PRBool;
var
tm: nsIThreadManager;
begin
NS_GetService(NS_THREADMANAGER_CONTRACTID, nsIThreadManager, tm);
Result := tm.isMainThread;
end;
procedure NS_DispatchToCurrentThread(aEvent: nsIRunnable);
var
tm: nsIThreadManager;
thread: nsIThread;
begin
NS_GetService(NS_THREADMANAGER_CONTRACTID, nsIThreadManager, tm);
thread := tm.currentThread;
thread.dispatch(aEvent, NS_DISPATCH_NORMAL);
end;
procedure NS_DispatchToMainThread(aEvent: nsIRunnable;
aDispatchFlags: PRUint32);
var
tm: nsIThreadManager;
thread: nsIThread;
begin
NS_GetService(NS_THREADMANAGER_CONTRACTID, nsIThreadManager, tm);
thread := tm.mainThread;
thread.dispatch(aEvent, aDispatchFlags);
end;
procedure NS_ProcessPendingEvents(aThread: nsIThread;
aTimeout: PRUint32);
var
start: PRUint32;
processedEvent: PRBool;
begin
if not Assigned(aThread) then
aThread := NS_GetCurrentThread;
start := timeGetTime();
while True do
begin
processedEvent := aThread.processNextEvent(False);
if not ProcessedEvent then
Break;
if (timeGetTime()-start)>aTimeout then
Break;
end;
end;
function NS_HasPendingEvents(aThread: nsIThread): PRBool;
begin
if not Assigned(aThread) then
aThread := NS_GetCurrentThread;
result := aThread.hasPendingEvents;
end;
function NS_ProcessNextEvent(aThread: nsIThread; aMayWait: PRBool): PRBool;
begin
if not Assigned(aThread) then
aThread := NS_GetCurrentThread;
result := aThread.processNextEvent(aMayWait);
end;
end.