123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- {% lkqueueeventer.inc included by levents.pas }
- {$ifdef BSD}
- { TLKQueueEventer }
- constructor TLKQueueEventer.Create;
- begin
- inherited Create;
- Inflate;
- FFreeSlot := 0;
- FTimeout.tv_sec := 0;
- FTimeout.tv_nsec := 0;
- FQueue := KQueue;
- if FQueue < 0 then
- raise Exception.Create('Unable to create kqueue: ' + StrError(fpGetErrno));
- end;
- destructor TLKQueueEventer.Destroy;
- begin
- fpClose(FQueue);
- inherited Destroy;
- end;
- function TLKQueueEventer.GetTimeout: Integer;
- begin
- Result := FTimeout.tv_sec + FTimeout.tv_nsec * 1000 * 1000;
- end;
- procedure TLKQueueEventer.SetTimeout(const Value: Integer);
- begin
- if Value >= 0 then begin
- FTimeout.tv_sec := Value div 1000;
- FTimeout.tv_nsec := (Value mod 1000) * 1000;
- end else begin
- FTimeout.tv_sec := -1;
- FTimeout.tv_nsec := 0;
- end;
- end;
- procedure TLKQueueEventer.HandleIgnoreRead(aHandle: TLHandle);
- const
- INBOOL: array[Boolean] of Integer = (EV_ENABLE, EV_DISABLE);
- begin
- EV_SET(@FChanges[FFreeSlot], aHandle.FHandle, EVFILT_READ,
- INBOOL[aHandle.IgnoreRead], 0, 0, Pointer(aHandle));
- Inc(FFreeSlot);
- if FFreeSlot > Length(FChanges) then
- Inflate;
- end;
- procedure TLKQueueEventer.Inflate;
- const
- BASE_SIZE = 100;
- var
- OldLength: Integer;
- begin
- OldLength := Length(FChanges);
- if OldLength > 1 then begin
- SetLength(FChanges, Sqr(OldLength));
- SetLength(FEvents, Sqr(OldLength));
- end else begin
- SetLength(FChanges, BASE_SIZE);
- SetLength(FEvents, BASE_SIZE);
- end;
- end;
- function TLKQueueEventer.AddHandle(aHandle: TLHandle): Boolean;
- begin
- Result := inherited AddHandle(aHandle);
- if FFreeSlot > Length(FChanges) then
- Inflate;
- EV_SET(@FChanges[FFreeSlot], aHandle.FHandle, EVFILT_WRITE,
- EV_ADD or EV_CLEAR, 0, 0, Pointer(aHandle));
- Inc(FFreeSlot);
- if FFreeSlot > Length(FChanges) then
- Inflate;
- if not aHandle.FIgnoreRead then begin
- EV_SET(@FChanges[FFreeSlot], aHandle.FHandle, EVFILT_READ,
- EV_ADD, 0, 0, Pointer(aHandle));
- Inc(FFreeSlot);
- end;
- end;
- function TLKQueueEventer.CallAction: Boolean;
- var
- i, n: Integer;
- Temp: TLHandle;
- begin
- Result := False;
- if FInLoop then
- Exit;
- if FTimeout.tv_sec >= 0 then
- n := KEvent(FQueue, @FChanges[0], FFreeSlot,
- @FEvents[0], Length(FEvents), @FTimeout)
- else
- n := KEvent(FQueue, @FChanges[0], FFreeSlot,
- @FEvents[0], Length(FEvents), nil);
- FFreeSlot := 0;
- if n < 0 then
- Bail('Error on kqueue', LSocketError);
- Result := n > 0;
- if Result then begin
- FInLoop := True;
- for i := 0 to n-1 do begin
- Temp := TLHandle(FEvents[i].uData);
-
- if (not Temp.FDispose)
- and (FEvents[i].Filter = EVFILT_WRITE) then
- if Assigned(Temp.FOnWrite) and not Temp.IgnoreWrite then
- Temp.FOnWrite(Temp);
- if (not Temp.FDispose)
- and (FEvents[i].Filter = EVFILT_READ) then
- if Assigned(Temp.FOnRead) and not Temp.IgnoreRead then
- Temp.FOnRead(Temp);
-
- if (not Temp.FDispose)
- and ((FEvents[i].Flags and EV_ERROR) > 0) then
- if Assigned(Temp.FOnError) and not Temp.IgnoreError then
- Temp.FOnError(Temp, 'Handle error' + LStrError(LSocketError));
- if Temp.FDispose then
- AddForFree(Temp);
- end;
- FInLoop := False;
- if Assigned(FFreeRoot) then
- FreeHandles;
- end;
- end;
- function BestEventerClass: TLEventerClass;
- begin
- {$IFNDEF FORCE_SELECT}
- Result := TLKQueueEventer;
- {$ELSE}
- Result := TLSelectEventer;
- {$ENDIF}
- end;
- {$endif} // BSD
|