|
@@ -34,7 +34,7 @@ type
|
|
|
HighestHandle: LongInt;
|
|
|
end;
|
|
|
|
|
|
-{$INCLUDE libasync.inc}
|
|
|
+{$INCLUDE libasynch.inc}
|
|
|
|
|
|
|
|
|
|
|
@@ -43,23 +43,13 @@ implementation
|
|
|
{$ifdef VER1_0}
|
|
|
uses Linux;
|
|
|
{$else}
|
|
|
-Uses Unix;
|
|
|
+uses Unix;
|
|
|
{$endif}
|
|
|
|
|
|
const
|
|
|
MaxHandle = SizeOf(TFDSet) * 8 - 1;
|
|
|
|
|
|
type
|
|
|
- PTimerData = ^TTimerData;
|
|
|
- TTimerData = record
|
|
|
- Next: PTimerData;
|
|
|
- MSec: LongInt;
|
|
|
- NextTick: Int64;
|
|
|
- Callback: TAsyncCallback;
|
|
|
- UserData: Pointer;
|
|
|
- Periodic: Boolean;
|
|
|
- end;
|
|
|
-
|
|
|
PIOCallbackData = ^TIOCallbackData;
|
|
|
TIOCallbackData = record
|
|
|
Next: PIOCallbackData;
|
|
@@ -69,242 +59,48 @@ type
|
|
|
SavedHandleFlags: LongInt;
|
|
|
end;
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-function InitIOCallback(Handle: TAsyncHandle; IOHandle: LongInt;
|
|
|
- ARead: Boolean; ReadCallback: TAsyncCallback; ReadUserData: Pointer;
|
|
|
- AWrite: Boolean; WriteCallback: TAsyncCallback; WriteUserData: Pointer):
|
|
|
- TAsyncResult;
|
|
|
-var
|
|
|
- Data: PIOCallbackData;
|
|
|
- i: LongInt;
|
|
|
- NeedData: Boolean;
|
|
|
-begin
|
|
|
- if IOHandle > MaxHandle then
|
|
|
- begin
|
|
|
- Result := asyncInvalidFileHandle;
|
|
|
- exit;
|
|
|
- end;
|
|
|
-
|
|
|
- NeedData := True;
|
|
|
- Data := Handle^.Data.FirstIOCallback;
|
|
|
- while Assigned(Data) do
|
|
|
- begin
|
|
|
- if Data^.IOHandle = IOHandle then
|
|
|
- begin
|
|
|
- if ARead then
|
|
|
- begin
|
|
|
- if Assigned(Data^.ReadCallback) then
|
|
|
- begin
|
|
|
- Result := asyncHandlerAlreadySet;
|
|
|
- exit;
|
|
|
- end;
|
|
|
- Data^.ReadCallback := ReadCallback;
|
|
|
- Data^.ReadUserData := ReadUserData;
|
|
|
- end;
|
|
|
- if AWrite then
|
|
|
- begin
|
|
|
- if Assigned(Data^.WriteCallback) then
|
|
|
- begin
|
|
|
- Result := asyncHandlerAlreadySet;
|
|
|
- exit;
|
|
|
- end;
|
|
|
- Data^.WriteCallback := WriteCallback;
|
|
|
- Data^.WriteUserData := WriteUserData;
|
|
|
- end;
|
|
|
- NeedData := False;
|
|
|
- break;
|
|
|
- end;
|
|
|
- Data := Data^.Next;
|
|
|
- end;
|
|
|
-
|
|
|
- if NeedData then
|
|
|
- begin
|
|
|
- New(Data);
|
|
|
- Data^.Next := Handle^.Data.FirstIOCallback;
|
|
|
- Handle^.Data.FirstIOCallback := Data;
|
|
|
- Data^.IOHandle := IOHandle;
|
|
|
- if ARead then
|
|
|
- begin
|
|
|
- Data^.ReadCallback := ReadCallback;
|
|
|
- Data^.ReadUserData := ReadUserData;
|
|
|
- end else
|
|
|
- Data^.ReadCallback := nil;
|
|
|
- if AWrite then
|
|
|
- begin
|
|
|
- Data^.WriteCallback := WriteCallback;
|
|
|
- Data^.WriteUserData := WriteUserData;
|
|
|
- end else
|
|
|
- Data^.WriteCallback := nil;
|
|
|
-
|
|
|
- if not Assigned(Handle^.Data.FDData) then
|
|
|
- begin
|
|
|
- GetMem(Handle^.Data.FDData, SizeOf(TFDSet) * 2);
|
|
|
- FD_Zero(PFDSet(Handle^.Data.FDData)[0]);
|
|
|
- FD_Zero(PFDSet(Handle^.Data.FDData)[1]);
|
|
|
- end;
|
|
|
- if IOHandle > Handle^.Data.HighestHandle then
|
|
|
- Handle^.Data.HighestHandle := IOHandle;
|
|
|
- end;
|
|
|
-
|
|
|
- Data^.SavedHandleFlags := fcntl(IOHandle, F_GetFl);
|
|
|
- fcntl(IOHandle, F_SetFl, Data^.SavedHandleFlags or Open_NonBlock);
|
|
|
-
|
|
|
- case IOHandle of
|
|
|
- StdInputHandle:
|
|
|
- i := Open_RdOnly;
|
|
|
- StdOutputHandle, StdErrorHandle:
|
|
|
- i := Open_WrOnly;
|
|
|
- else
|
|
|
- i := Data^.SavedHandleFlags and Open_Accmode;
|
|
|
- end;
|
|
|
-
|
|
|
- case i of
|
|
|
- Open_RdOnly:
|
|
|
- if ARead then
|
|
|
- FD_Set(IOHandle, PFDSet(Handle^.Data.FDData)[0]);
|
|
|
- Open_WrOnly:
|
|
|
- if AWrite then
|
|
|
- FD_Set(IOHandle, PFDSet(Handle^.Data.FDData)[1]);
|
|
|
- Open_RdWr:
|
|
|
- begin
|
|
|
- if ARead then
|
|
|
- FD_Set(IOHandle, PFDSet(Handle^.Data.FDData)[0]);
|
|
|
- if AWrite then
|
|
|
- FD_Set(IOHandle, PFDSet(Handle^.Data.FDData)[1]);
|
|
|
- end;
|
|
|
- end;
|
|
|
-
|
|
|
- Handle^.Data.HasCallbacks := True;
|
|
|
- Result := asyncOK;
|
|
|
-end;
|
|
|
-
|
|
|
-procedure CheckForCallbacks(Handle: TAsyncHandle);
|
|
|
-var
|
|
|
- Data: PIOCallbackData;
|
|
|
-begin
|
|
|
- if (Handle^.Data.HasCallbacks) and
|
|
|
- (not Assigned(Handle^.Data.FirstIOCallback)) and
|
|
|
- (not Assigned(Handle^.Data.FirstTimer)) then
|
|
|
- Handle^.Data.HasCallbacks := False;
|
|
|
-end;
|
|
|
+{$INCLUDE libasync.inc}
|
|
|
|
|
|
|
|
|
|
|
|
-procedure asyncInit(Handle: TAsyncHandle); cdecl;
|
|
|
+procedure InternalInit(Handle: TAsyncHandle);
|
|
|
begin
|
|
|
Handle^.Data.HighestHandle := -1;
|
|
|
end;
|
|
|
|
|
|
-procedure asyncFree(Handle: TAsyncHandle); cdecl;
|
|
|
+procedure InternalFree(Handle: TAsyncHandle);
|
|
|
var
|
|
|
- Timer, NextTimer: PTimerData;
|
|
|
- IOCallback, NextIOCallback: PIOCallbackData;
|
|
|
+ IOCallback: PIOCallbackData;
|
|
|
begin
|
|
|
- Timer := PTimerData(Handle^.Data.FirstTimer);
|
|
|
- while Assigned(Timer) do
|
|
|
- begin
|
|
|
- NextTimer := Timer^.Next;
|
|
|
- Dispose(Timer);
|
|
|
- Timer := NextTimer;
|
|
|
- end;
|
|
|
-
|
|
|
IOCallback := PIOCallbackData(Handle^.Data.FirstIOCallback);
|
|
|
while Assigned(IOCallback) do
|
|
|
begin
|
|
|
if (IOCallback^.SavedHandleFlags and Open_NonBlock) = 0 then
|
|
|
fcntl(IOCallback^.IOHandle, F_SetFl, IOCallback^.SavedHandleFlags);
|
|
|
- NextIOCallback := IOCallback^.Next;
|
|
|
- Dispose(IOCallback);
|
|
|
- IOCallback := NextIOCallback;
|
|
|
+ IOCallback := IOCallback^.Next;
|
|
|
end;
|
|
|
|
|
|
- Handle^.Data.NextIOCallback := nil;
|
|
|
-
|
|
|
if Assigned(Handle^.Data.FDData) then
|
|
|
FreeMem(Handle^.Data.FDData);
|
|
|
end;
|
|
|
|
|
|
-procedure asyncRun(Handle: TAsyncHandle); cdecl;
|
|
|
+procedure InternalRun(Handle: TAsyncHandle; TimeOut: Int64);
|
|
|
var
|
|
|
- Timer, NextTimer: PTimerData;
|
|
|
- TimeOut, AsyncResult: Integer;
|
|
|
- CurTime, NextTick: Int64;
|
|
|
+ AsyncResult: Integer;
|
|
|
CurReadFDSet, CurWriteFDSet: TFDSet;
|
|
|
CurIOCallback: PIOCallbackData;
|
|
|
begin
|
|
|
- if Handle^.Data.IsRunning then
|
|
|
- exit;
|
|
|
-
|
|
|
- Handle^.Data.DoBreak := False;
|
|
|
- Handle^.Data.IsRunning := True;
|
|
|
-
|
|
|
- // Prepare timers
|
|
|
- if Assigned(Handle^.Data.FirstTimer) then
|
|
|
+ if Handle^.Data.HighestHandle < 0 then
|
|
|
+ // No I/O checks to do, so just wait...
|
|
|
+ AsyncResult := Select(0, nil, nil, nil, TimeOut)
|
|
|
+ else
|
|
|
begin
|
|
|
- CurTime := asyncGetTicks;
|
|
|
- Timer := Handle^.Data.FirstTimer;
|
|
|
- while Assigned(Timer) do
|
|
|
- begin
|
|
|
- Timer^.NextTick := CurTime + Timer^.MSec;
|
|
|
- Timer := Timer^.Next;
|
|
|
- end;
|
|
|
- end;
|
|
|
-
|
|
|
- while (not Handle^.Data.DoBreak) and Handle^.Data.HasCallbacks do
|
|
|
- begin
|
|
|
- Timer := Handle^.Data.FirstTimer;
|
|
|
- if Assigned(Handle^.Data.FirstTimer) then
|
|
|
- begin
|
|
|
- // Determine when the next timer tick will happen
|
|
|
- CurTime := asyncGetTicks;
|
|
|
- NextTick := High(Int64);
|
|
|
- Timer := Handle^.Data.FirstTimer;
|
|
|
- while Assigned(Timer) do
|
|
|
- begin
|
|
|
- if Timer^.NextTick < NextTick then
|
|
|
- NextTick := Timer^.NextTick;
|
|
|
- Timer := Timer^.Next;
|
|
|
- end;
|
|
|
- TimeOut := NextTick - CurTime;
|
|
|
- if TimeOut < 0 then
|
|
|
- TimeOut := 0;
|
|
|
- end else
|
|
|
- TimeOut := -1;
|
|
|
-
|
|
|
- if Handle^.Data.HighestHandle >= 0 then
|
|
|
- begin
|
|
|
- CurReadFDSet := PFDSet(Handle^.Data.FDData)[0];
|
|
|
- CurWriteFDSet := PFDSet(Handle^.Data.FDData)[1];
|
|
|
- AsyncResult := Select(Handle^.Data.HighestHandle + 1,
|
|
|
- @CurReadFDSet, @CurWriteFDSet, nil, TimeOut);
|
|
|
- end else
|
|
|
- AsyncResult := Select(0, nil, nil, nil, TimeOut);
|
|
|
-
|
|
|
- if Assigned(Handle^.Data.FirstTimer) then
|
|
|
- begin
|
|
|
- // Check for triggered timers
|
|
|
- CurTime := asyncGetTicks;
|
|
|
- Timer := Handle^.Data.FirstTimer;
|
|
|
- while Assigned(Timer) do
|
|
|
- begin
|
|
|
- if Timer^.NextTick <= CurTime then
|
|
|
- begin
|
|
|
- Timer^.Callback(Timer^.UserData);
|
|
|
- NextTimer := Timer^.Next;
|
|
|
- if Timer^.Periodic then
|
|
|
- Inc(Timer^.NextTick, Timer^.MSec)
|
|
|
- else
|
|
|
- asyncRemoveTimer(Handle, Timer);
|
|
|
- if Handle^.Data.DoBreak then
|
|
|
- break;
|
|
|
- Timer := NextTimer;
|
|
|
- end else
|
|
|
- Timer := Timer^.Next;
|
|
|
- end;
|
|
|
- end;
|
|
|
+ CurReadFDSet := PFDSet(Handle^.Data.FDData)[0];
|
|
|
+ CurWriteFDSet := PFDSet(Handle^.Data.FDData)[1];
|
|
|
+ AsyncResult := Select(Handle^.Data.HighestHandle + 1,
|
|
|
+ @CurReadFDSet, @CurWriteFDSet, nil, TimeOut);
|
|
|
|
|
|
- if (AsyncResult > 0) and not Handle^.Data.DoBreak then
|
|
|
+ if AsyncResult > 0 then
|
|
|
begin
|
|
|
// Check for I/O events
|
|
|
Handle^.Data.CurIOCallback := Handle^.Data.FirstIOCallback;
|
|
@@ -312,236 +108,93 @@ begin
|
|
|
begin
|
|
|
CurIOCallback := PIOCallbackData(Handle^.Data.CurIOCallback);
|
|
|
Handle^.Data.NextIOCallback := CurIOCallback^.Next;
|
|
|
- if FD_IsSet(CurIOCallback^.IOHandle, CurReadFDSet) and
|
|
|
+ if FD_IsSet(CurIOCallback^.IOHandle, CurReadFDSet) and
|
|
|
FD_IsSet(CurIOCallback^.IOHandle, PFDSet(Handle^.Data.FDData)[0]) and
|
|
|
Assigned(CurIOCallback^.ReadCallback) then
|
|
|
- begin
|
|
|
+ begin
|
|
|
CurIOCallback^.ReadCallback(CurIOCallback^.ReadUserData);
|
|
|
if Handle^.Data.DoBreak then
|
|
|
break;
|
|
|
- end;
|
|
|
+ end;
|
|
|
|
|
|
- CurIOCallback := PIOCallbackData(Handle^.Data.CurIOCallback);
|
|
|
- if Assigned(CurIOCallback) and
|
|
|
+ CurIOCallback := PIOCallbackData(Handle^.Data.CurIOCallback);
|
|
|
+ if Assigned(CurIOCallback) and
|
|
|
FD_IsSet(CurIOCallback^.IOHandle, CurWriteFDSet) and
|
|
|
FD_IsSet(CurIOCallback^.IOHandle, PFDSet(Handle^.Data.FDData)[1]) and
|
|
|
Assigned(CurIOCallback^.WriteCallback) then
|
|
|
- begin
|
|
|
+ begin
|
|
|
CurIOCallback^.WriteCallback(CurIOCallback^.WriteUserData);
|
|
|
if Handle^.Data.DoBreak then
|
|
|
break;
|
|
|
- end;
|
|
|
+ end;
|
|
|
|
|
|
- Handle^.Data.CurIOCallback := Handle^.Data.NextIOCallback;
|
|
|
+ Handle^.Data.CurIOCallback := Handle^.Data.NextIOCallback;
|
|
|
end;
|
|
|
end;
|
|
|
end;
|
|
|
- Handle^.Data.CurIOCallback := nil;
|
|
|
- Handle^.Data.NextIOCallback := nil;
|
|
|
- Handle^.Data.IsRunning := False;
|
|
|
-end;
|
|
|
-
|
|
|
-procedure asyncBreak(Handle: TAsyncHandle); cdecl;
|
|
|
-begin
|
|
|
- Handle^.Data.DoBreak := True;
|
|
|
-end;
|
|
|
-
|
|
|
-function asyncIsRunning(Handle: TAsyncHandle): Boolean; cdecl;
|
|
|
-begin
|
|
|
- Result := Handle^.Data.IsRunning;
|
|
|
-end;
|
|
|
-
|
|
|
-function asyncGetTicks: Int64; cdecl;
|
|
|
-var
|
|
|
- Time: TimeVal;
|
|
|
-begin
|
|
|
- GetTimeOfDay(Time);
|
|
|
- Result := Int64(Time.Sec) * 1000 + Int64(Time.USec div 1000);
|
|
|
end;
|
|
|
|
|
|
-function asyncAddTimer(
|
|
|
- Handle: TAsyncHandle;
|
|
|
- MSec: LongInt;
|
|
|
- Periodic: Boolean;
|
|
|
- Callback: TAsyncCallback;
|
|
|
- UserData: Pointer
|
|
|
- ): TAsyncTimer; cdecl;
|
|
|
+procedure InternalInitIOCallback(Handle: TAsyncHandle; Data: PIOCallbackData;
|
|
|
+ InitData: Boolean; CallbackTypes: TCallbackTypes);
|
|
|
var
|
|
|
- Data: PTimerData;
|
|
|
-begin
|
|
|
- if not Assigned(Callback) then
|
|
|
- exit;
|
|
|
-
|
|
|
- New(Data);
|
|
|
- Result := Data;
|
|
|
- Data^.Next := Handle^.Data.FirstTimer;
|
|
|
- Handle^.Data.FirstTimer := Data;
|
|
|
- Data^.MSec := MSec;
|
|
|
- Data^.Periodic := Periodic;
|
|
|
- Data^.Callback := Callback;
|
|
|
- Data^.UserData := UserData;
|
|
|
- if Handle^.Data.IsRunning then
|
|
|
- Data^.NextTick := asyncGetTicks + MSec;
|
|
|
-
|
|
|
- Handle^.Data.HasCallbacks := True;
|
|
|
-end;
|
|
|
-
|
|
|
-procedure asyncRemoveTimer(
|
|
|
- Handle: TAsyncHandle;
|
|
|
- Timer: TASyncTimer); cdecl;
|
|
|
-var
|
|
|
- Data, CurData, PrevData, NextData: PTimerData;
|
|
|
+ i: LongInt;
|
|
|
begin
|
|
|
- Data := PTimerData(Timer);
|
|
|
- CurData := Handle^.Data.FirstTimer;
|
|
|
- PrevData := nil;
|
|
|
- while Assigned(CurData) do
|
|
|
+ if InitData then
|
|
|
begin
|
|
|
- NextData := CurData^.Next;
|
|
|
- if CurData = Data then
|
|
|
+ if not Assigned(Handle^.Data.FDData) then
|
|
|
begin
|
|
|
- if Assigned(PrevData) then
|
|
|
- PrevData^.Next := NextData
|
|
|
- else
|
|
|
- Handle^.Data.FirstTimer := NextData;
|
|
|
- break;
|
|
|
+ GetMem(Handle^.Data.FDData, SizeOf(TFDSet) * 2);
|
|
|
+ FD_Zero(PFDSet(Handle^.Data.FDData)[0]);
|
|
|
+ FD_Zero(PFDSet(Handle^.Data.FDData)[1]);
|
|
|
end;
|
|
|
- PrevData := CurData;
|
|
|
- CurData := NextData;
|
|
|
+ if Data^.IOHandle > Handle^.Data.HighestHandle then
|
|
|
+ Handle^.Data.HighestHandle := Data^.IOHandle;
|
|
|
end;
|
|
|
- Dispose(Data);
|
|
|
- CheckForCallbacks(Handle);
|
|
|
-end;
|
|
|
|
|
|
-function asyncSetIOCallback(
|
|
|
- Handle: TAsyncHandle;
|
|
|
- IOHandle: LongInt;
|
|
|
- Callback: TAsyncCallback;
|
|
|
- UserData: Pointer): TAsyncResult; cdecl;
|
|
|
-begin
|
|
|
- Result := InitIOCallback(Handle, IOHandle, True, Callback, UserData,
|
|
|
- True, Callback, UserData);
|
|
|
-end;
|
|
|
+ Data^.SavedHandleFlags := fcntl(Data^.IOHandle, F_GetFl);
|
|
|
+ fcntl(Data^.IOHandle, F_SetFl, Data^.SavedHandleFlags or Open_NonBlock);
|
|
|
|
|
|
-procedure asyncClearIOCallback(Handle: TAsyncHandle;
|
|
|
- IOHandle: LongInt); cdecl;
|
|
|
-var
|
|
|
- CurData, PrevData, NextData: PIOCallbackData;
|
|
|
-begin
|
|
|
- CurData := Handle^.Data.FirstIOCallback;
|
|
|
- PrevData := nil;
|
|
|
- while Assigned(CurData) do
|
|
|
- begin
|
|
|
- NextData := CurData^.Next;
|
|
|
- if CurData^.IOHandle = IOHandle then
|
|
|
- begin
|
|
|
- if Handle^.Data.CurIOCallback = CurData then
|
|
|
- Handle^.Data.CurIOCallback := nil;
|
|
|
- if Handle^.Data.NextIOCallback = CurData then
|
|
|
- Handle^.Data.NextIOCallback := NextData;
|
|
|
- FD_Clr(IOHandle, PFDSet(Handle^.Data.FDData)[0]);
|
|
|
- FD_Clr(IOHandle, PFDSet(Handle^.Data.FDData)[1]);
|
|
|
- if Assigned(PrevData) then
|
|
|
- PrevData^.Next := NextData
|
|
|
- else
|
|
|
- Handle^.Data.FirstIOCallback := NextData;
|
|
|
- Dispose(CurData);
|
|
|
- break;
|
|
|
- end;
|
|
|
- PrevData := CurData;
|
|
|
- CurData := NextData;
|
|
|
+ case Data^.IOHandle of
|
|
|
+ StdInputHandle:
|
|
|
+ i := Open_RdOnly;
|
|
|
+ StdOutputHandle, StdErrorHandle:
|
|
|
+ i := Open_WrOnly;
|
|
|
+ else
|
|
|
+ i := Data^.SavedHandleFlags and Open_Accmode;
|
|
|
end;
|
|
|
- CheckForCallbacks(Handle);
|
|
|
-end;
|
|
|
|
|
|
-function asyncSetDataAvailableCallback(
|
|
|
- Handle: TAsyncHandle;
|
|
|
- IOHandle: LongInt;
|
|
|
- Callback: TAsyncCallback;
|
|
|
- UserData: Pointer): TAsyncResult; cdecl;
|
|
|
-begin
|
|
|
- Result := InitIOCallback(Handle, IOHandle, True, Callback, UserData, False,
|
|
|
- nil, nil);
|
|
|
-end;
|
|
|
-
|
|
|
-procedure asyncClearDataAvailableCallback(Handle: TAsyncHandle;
|
|
|
- IOHandle: LongInt); cdecl;
|
|
|
-var
|
|
|
- CurData, PrevData, NextData: PIOCallbackData;
|
|
|
-begin
|
|
|
- CurData := Handle^.Data.FirstIOCallback;
|
|
|
- PrevData := nil;
|
|
|
- while Assigned(CurData) do
|
|
|
- begin
|
|
|
- NextData := CurData^.Next;
|
|
|
- if CurData^.IOHandle = IOHandle then
|
|
|
- begin
|
|
|
- if Handle^.Data.CurIOCallback = CurData then
|
|
|
- Handle^.Data.CurIOCallback := nil;
|
|
|
- if Handle^.Data.NextIOCallback = CurData then
|
|
|
- Handle^.Data.NextIOCallback := NextData;
|
|
|
- FD_Clr(IOHandle, PFDSet(Handle^.Data.FDData)[0]);
|
|
|
- if Assigned(CurData^.WriteCallback) then
|
|
|
- CurData^.ReadCallback := nil
|
|
|
- else
|
|
|
+ case i of
|
|
|
+ Open_RdOnly:
|
|
|
+ if cbRead in CallbackTypes then
|
|
|
+ FD_Set(Data^.IOHandle, PFDSet(Handle^.Data.FDData)[0]);
|
|
|
+ Open_WrOnly:
|
|
|
+ if cbWrite in CallbackTypes then
|
|
|
+ FD_Set(Data^.IOHandle, PFDSet(Handle^.Data.FDData)[1]);
|
|
|
+ Open_RdWr:
|
|
|
begin
|
|
|
- if Assigned(PrevData) then
|
|
|
- PrevData^.Next := NextData
|
|
|
- else
|
|
|
- Handle^.Data.FirstIOCallback := NextData;
|
|
|
- Dispose(CurData);
|
|
|
+ if cbRead in CallbackTypes then
|
|
|
+ FD_Set(Data^.IOHandle, PFDSet(Handle^.Data.FDData)[0]);
|
|
|
+ if cbWrite in CallbackTypes then
|
|
|
+ FD_Set(Data^.IOHandle, PFDSet(Handle^.Data.FDData)[1]);
|
|
|
end;
|
|
|
- break;
|
|
|
- end;
|
|
|
- PrevData := CurData;
|
|
|
- CurData := NextData;
|
|
|
end;
|
|
|
- CheckForCallbacks(Handle);
|
|
|
end;
|
|
|
|
|
|
-function asyncSetCanWriteCallback(
|
|
|
- Handle: TAsyncHandle;
|
|
|
- IOHandle: LongInt;
|
|
|
- Callback: TAsyncCallback;
|
|
|
- UserData: Pointer): TAsyncResult; cdecl;
|
|
|
+procedure InternalClearIOCallback(Handle: TAsyncHandle; IOHandle: LongInt;
|
|
|
+ CallbackTypes: TCallbackTypes);
|
|
|
begin
|
|
|
- Result := InitIOCallback(Handle, IOHandle, False, nil, nil, True,
|
|
|
- Callback, UserData);
|
|
|
+ if cbRead in CallbackTypes then
|
|
|
+ FD_Clr(IOHandle, PFDSet(Handle^.Data.FDData)[0]);
|
|
|
+ if cbWrite in CallbackTypes then
|
|
|
+ FD_Clr(IOHandle, PFDSet(Handle^.Data.FDData)[1]);
|
|
|
end;
|
|
|
|
|
|
-procedure asyncClearCanWriteCallback(Handle: TAsyncHandle;
|
|
|
- IOHandle: LongInt); cdecl;
|
|
|
+function asyncGetTicks: Int64; cdecl;
|
|
|
var
|
|
|
- CurData, PrevData, NextData: PIOCallbackData;
|
|
|
+ Time: TimeVal;
|
|
|
begin
|
|
|
- CurData := Handle^.Data.FirstIOCallback;
|
|
|
- PrevData := nil;
|
|
|
- while Assigned(CurData) do
|
|
|
- begin
|
|
|
- NextData := CurData^.Next;
|
|
|
- if CurData^.IOHandle = IOHandle then
|
|
|
- begin
|
|
|
- if Handle^.Data.CurIOCallback = CurData then
|
|
|
- Handle^.Data.CurIOCallback := nil;
|
|
|
- if Handle^.Data.NextIOCallback = CurData then
|
|
|
- Handle^.Data.NextIOCallback := NextData;
|
|
|
- FD_Clr(IOHandle, PFDSet(Handle^.Data.FDData)[1]);
|
|
|
- if Assigned(CurData^.ReadCallback) then
|
|
|
- CurData^.WriteCallback := nil
|
|
|
- else
|
|
|
- begin
|
|
|
- if Assigned(PrevData) then
|
|
|
- PrevData^.Next := NextData
|
|
|
- else
|
|
|
- Handle^.Data.FirstIOCallback := NextData;
|
|
|
- Dispose(CurData);
|
|
|
- end;
|
|
|
- break;
|
|
|
- end;
|
|
|
- PrevData := CurData;
|
|
|
- CurData := NextData;
|
|
|
- end;
|
|
|
- CheckForCallbacks(Handle);
|
|
|
+ GetTimeOfDay(Time);
|
|
|
+ Result := Int64(Time.Sec) * 1000 + Int64(Time.USec div 1000);
|
|
|
end;
|
|
|
|
|
|
|
|
@@ -550,13 +203,9 @@ end.
|
|
|
|
|
|
{
|
|
|
$Log$
|
|
|
- Revision 1.4 2002-09-15 15:51:09 sg
|
|
|
- * Removed debugging output code
|
|
|
-
|
|
|
- Revision 1.3 2002/09/15 15:43:30 sg
|
|
|
- * Improved error reporting
|
|
|
-
|
|
|
- Revision 1.1 2002/01/29 17:54:53 peter
|
|
|
- * splitted to base and extra
|
|
|
+ Revision 1.5 2002-09-25 21:53:39 sg
|
|
|
+ * Split in common implementation an platform dependent implementation
|
|
|
|
|
|
+ Revision 1.4 2002/09/15 15:51:09 sg
|
|
|
+ * Removed debugging output code
|
|
|
}
|