asyncio.inc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 1999-2000 by the Free Pascal development team
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. procedure TAsyncIOManager.CalcHighestHandle(max: Integer);
  11. var
  12. i: Integer;
  13. begin
  14. With IOData do
  15. begin
  16. HighestHandle := -1;
  17. for i := max downto 0 do
  18. if FD_IsSet(i, ReadMap) or FD_IsSet(i, WriteMap) then begin
  19. HighestHandle := i;
  20. break;
  21. end;
  22. end;
  23. end;
  24. function TAsyncIOManager.GetHandleAsync(AHandle: Integer): Boolean;
  25. begin
  26. Result := (fcntl(AHandle, F_GetFl) and Open_NonBlock) <> 0;
  27. end;
  28. procedure TAsyncIOManager.SetHandleAsync(AHandle: Integer; AValue: Boolean);
  29. var
  30. SavedBits: Integer;
  31. begin
  32. SavedBits := fcntl(AHandle, F_GetFl) and not Open_NonBlock;
  33. if AValue then
  34. fcntl(AHandle, F_SetFl, SavedBits or Open_NonBlock)
  35. else
  36. fcntl(AHandle, F_SetFl, SavedBits);
  37. end;
  38. constructor TAsyncIOManager.Create;
  39. begin
  40. inherited Create;
  41. With IOdata do
  42. begin
  43. FD_Zero(ReadMap);
  44. FD_Zero(WriteMap);
  45. end;
  46. HighestHandle := -1;
  47. end;
  48. procedure TAsyncIOManager.Run;
  49. var
  50. ThisReadMap, ThisWriteMap: TFDSet;
  51. i, res: Integer;
  52. begin
  53. DoBreak := False;
  54. With IOdata do
  55. begin
  56. while (not DoBreak) and ((HighestHandle >= 0) or (FTimeout > 0)) do begin
  57. ThisReadMap := ReadMap;
  58. ThisWriteMap := WriteMap;
  59. if FTimeout > 0 then
  60. res := Select(HighestHandle + 1, @ThisReadMap, @ThisWriteMap, nil, FTimeout)
  61. else
  62. res := Select(HighestHandle + 1, @ThisReadMap, @ThisWriteMap, nil, nil);
  63. if res < 0 then
  64. break;
  65. if res = 0 then
  66. ExecuteNotify(TimeoutNotify)
  67. else
  68. for i := 0 to HighestHandle do begin
  69. if FD_IsSet(i, ThisReadMap) and FD_IsSet(i, ReadMap)then
  70. ExecuteNotify(ReadNotifies[i]);
  71. if FD_IsSet(i, ThisWriteMap) and FD_IsSet(i, WriteMap) then
  72. ExecuteNotify(WriteNotifies[i]);
  73. end;
  74. end;
  75. end;
  76. end;
  77. procedure TAsyncIOManager.BreakRun;
  78. begin
  79. DoBreak := True;
  80. end;
  81. procedure TAsyncIOManager.SetReadHandler(AHandle: Integer;
  82. AMethod: TAsyncIONotify; AUserData: TObject);
  83. begin
  84. ASSERT((AHandle >= 0) and (AHandle <= MaxHandle) and Assigned(AMethod));
  85. if (AHandle < 0) or (AHandle > MaxHandle) then
  86. exit;
  87. if AHandle > HighestHandle then
  88. HighestHandle := AHandle;
  89. FD_Set(AHandle, IOdata.ReadMap);
  90. ReadNotifies[AHandle].Method := AMethod;
  91. ReadNotifies[AHandle].UserData := AUserData;
  92. end;
  93. procedure TAsyncIOManager.ClearReadHandler(AHandle: Integer);
  94. begin
  95. ASSERT((AHandle >= 0) and (AHandle <= MaxHandle));
  96. if (AHandle >= 0) and (AHandle <= MaxHandle) then
  97. begin
  98. FD_Clr(AHandle, IOdata.ReadMap);
  99. if AHandle = HighestHandle then
  100. CalcHighestHandle(AHandle);
  101. end;
  102. end;
  103. function TAsyncIOManager.GetReadHandler(AHandle: Integer): TAsyncIONotify;
  104. begin
  105. ASSERT((AHandle >= 0) and (AHandle <= MaxHandle));
  106. if (AHandle < 0) or (AHandle > MaxHandle) then
  107. Result := nil
  108. else
  109. Result := ReadNotifies[AHandle].Method;
  110. end;
  111. procedure TAsyncIOManager.SetWriteHandler(AHandle: Integer;
  112. AMethod: TAsyncIONotify; AUserData: TObject);
  113. begin
  114. ASSERT((AHandle >= 0) and (AHandle <= MaxHandle) and Assigned(AMethod));
  115. if (AHandle < 0) or (AHandle > MaxHandle) then
  116. exit;
  117. if AHandle > HighestHandle then
  118. HighestHandle := AHandle;
  119. FD_Set(AHandle, IOData.WriteMap);
  120. WriteNotifies[AHandle].Method := AMethod;
  121. WriteNotifies[AHandle].UserData := AUserData;
  122. end;
  123. procedure TAsyncIOManager.ClearWriteHandler(AHandle: Integer);
  124. begin
  125. ASSERT((AHandle >= 0) and (AHandle <= MaxHandle));
  126. if (AHandle >= 0) and (AHandle <= MaxHandle) then begin
  127. FD_Clr(AHandle, IOdata.WriteMap);
  128. if AHandle = HighestHandle then
  129. CalcHighestHandle(AHandle);
  130. end;
  131. end;
  132. function TAsyncIOManager.GetWriteHandler(AHandle: Integer): TAsyncIONotify;
  133. begin
  134. ASSERT((AHandle >= 0) and (AHandle <= MaxHandle));
  135. if (AHandle < 0) or (AHandle > MaxHandle) then
  136. Result := nil
  137. else
  138. Result := WriteNotifies[AHandle].Method;
  139. end;