Changeset 294 for PinConnection/UCommProtocol.pas
- Timestamp:
- Nov 15, 2011, 8:39:23 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
PinConnection/UCommProtocol.pas
r283 r294 33 33 public 34 34 Lock: TCriticalSection; 35 Enabled: Boolean; 35 36 SequenceNumber: Integer; 36 37 ResponseCode: Integer; … … 51 52 public 52 53 SequenceNumber: integer; 54 MaxSequenceNumber: integer; 55 MaxSessionCount: integer; 53 56 Parent: TCommProtocol; 54 57 Lock: TCriticalSection; … … 58 61 constructor Create; 59 62 destructor Destroy; override; 63 procedure Assign(Source: TListObject); 60 64 end; 61 65 … … 66 70 { TRetransmitCheckThread } 67 71 68 TRetransmitCheckThread = class(T ListedThread)72 TRetransmitCheckThread = class(TTermThread) 69 73 public 70 74 Parent: TCommProtocol; 71 75 CheckPeriod: Integer; 72 76 procedure Execute; override; 77 end; 78 79 { TRemoteBuffer } 80 81 TRemoteBuffer = class 82 Lock: TCriticalSection; 83 Size: Integer; 84 Used: Integer; 85 procedure Allocate(AValue: Integer); 86 procedure Release(AValue: Integer); 87 procedure Assign(Source: TRemoteBuffer); 88 constructor Create; 89 destructor Destroy; override; 73 90 end; 74 91 … … 89 106 RetransmitRepeatCount: integer; 90 107 RetransmitTotalCount: integer; 91 MaxSequenceNumber: integer; 92 MaxSessionCount: integer; 93 RemoteBufferSize: Integer; 94 RemoteBufferUsed: Integer; 108 RemoteBuffer: TRemoteBuffer; 95 109 WrongSequenceCount: integer; 96 110 Sessions: TDeviceProtocolSessionList; … … 98 112 LastCommandResponseTime: TDateTime; 99 113 LastLatency: TDateTime; 114 Lock: TCriticalSection; 100 115 procedure DataReceive(Sender: TCommPin; Stream: TStream); virtual; 101 116 procedure SendCommand(Command: array of integer; … … 112 127 113 128 resourcestring 129 SRemoteBufferInconsistency = 'Remote buffer inconsistency'; 114 130 SResponseError = 'Command %0:s response error %1:s'; 115 131 SResponseTimeout = 'Response timeout'; … … 120 136 121 137 implementation 138 139 { TRemoteBuffer } 140 141 procedure TRemoteBuffer.Allocate(AValue: Integer); 142 begin 143 try 144 Lock.Acquire; 145 146 // Wait for free remote buffer 147 while (Used + AValue) > Size do 148 try 149 Lock.Release; 150 Sleep(1); 151 finally 152 Lock.Acquire; 153 end; 154 Used := Used + AValue; 155 finally 156 Lock.Release; 157 end; 158 end; 159 160 procedure TRemoteBuffer.Release(AValue: Integer); 161 begin 162 try 163 Lock.Acquire; 164 Used := Used - AValue; 165 if Used < 0 then 166 raise Exception.Create(SRemoteBufferInconsistency); 167 finally 168 Lock.Release; 169 end; 170 end; 171 172 procedure TRemoteBuffer.Assign(Source: TRemoteBuffer); 173 begin 174 Used := Source.Used; 175 Size := Source.Size; 176 end; 177 178 constructor TRemoteBuffer.Create; 179 begin 180 Lock := TCriticalSection.Create; 181 Size := 127; 182 Used := 0; 183 end; 184 185 destructor TRemoteBuffer.Destroy; 186 begin 187 Lock.Free; 188 inherited Destroy; 189 end; 122 190 123 191 … … 159 227 else CommandError := 0; 160 228 Latency := Now - TransmitTime; 229 Enabled := False; 161 230 ReceiveEvent.SetEvent; 162 231 finally … … 253 322 254 323 procedure TCommProtocol.SetActive(const AValue: Boolean); 255 var256 SessionCount: Integer;257 324 begin 258 325 if FActive = AValue then Exit; … … 269 336 end else begin 270 337 // Wait for empty session list 271 repeat 338 try 339 Sessions.Lock.Acquire; 340 while Sessions.Count > 0 do 272 341 try 342 Sessions.Lock.Release; 343 Sleep(1); 344 finally 273 345 Sessions.Lock.Acquire; 274 SessionCount := Sessions.Count;275 finally276 Sessions.Lock.Release;277 346 end; 278 Sleep(1);279 until SessionCount = 0;280 347 finally 348 Sessions.Lock.Release; 349 end; 281 350 FreeAndNil(RetransmitThread); 282 351 end; … … 292 361 if FActive then begin 293 362 try 363 //Lock.Acquire; 294 364 Session := TDeviceProtocolSession.Create; 295 365 Sessions.Add(Session); … … 313 383 NewRequest.WriteToStream(Request); 314 384 315 // Wait for free remote buffer 316 while (RemoteBufferUsed + Request.Size) > RemoteBufferSize do 317 Sleep(1); 385 RemoteBuffer.Allocate(Request.Size); 318 386 319 387 //StopWatch.Start; 320 388 TransmitTime := Now; 321 389 Pin.Send(Request); 390 Enabled := True; 322 391 finally 323 392 Lock.Release; 324 393 end; 325 394 try 326 try 327 Sessions.Lock.Acquire; 328 RemoteBufferUsed := RemoteBufferUsed + Request.Size; 329 finally 330 Sessions.Lock.Release; 331 end; 332 while ReceiveEvent.WaitFor(10) = wrTimeout do begin 395 while ReceiveEvent.WaitFor(1) = wrTimeout do begin 333 396 if Timeouted then 334 397 raise ECommTimeout.Create(SResponseTimeout); … … 342 405 LastLatency := Latency; 343 406 finally 344 try 345 Sessions.Lock.Acquire; 346 RemoteBufferUsed := RemoteBufferUsed - Session.Request.Size; 347 if RemoteBufferUsed < 0 then RemoteBufferUsed := 0; 348 finally 349 Sessions.Lock.Release; 350 end; 407 RemoteBuffer.Release(Session.Request.Size); 351 408 Sessions.Remove(Session); 352 409 end; … … 354 411 finally 355 412 NewRequest.Free; 413 //Lock.Free; 356 414 end; 357 415 end else raise ENotActive.Create(SProtocolNotActive); … … 360 418 constructor TCommProtocol.Create; 361 419 begin 420 RemoteBuffer := TRemoteBuffer.Create; 421 Lock := TCriticalSection.Create; 362 422 Pin := TCommPin.Create; 363 423 Pin.OnReceive := DataReceive; 364 424 Sessions := TDeviceProtocolSessionList.Create; 365 425 Sessions.Parent := Self; 366 MaxSessionCount := 10; 367 MaxSequenceNumber := 127; 368 RetransmitTimeout := 2 * OneSecond; 426 RetransmitTimeout := 3 * OneSecond; 369 427 RetransmitRepeatCount := 3; 370 428 RetransmitTotalCount := 0; 371 RemoteBufferSize := 127;372 429 end; 373 430 … … 377 434 Sessions.Free; 378 435 Pin.Free; 379 inherited Destroy; 436 Lock.Free; 437 RemoteBuffer.Free; 438 inherited; 380 439 end; 381 440 … … 384 443 LastCommandResponseTime := Source.LastCommandResponseTime; 385 444 LastLatency := Source.LastLatency; 386 MaxSequenceNumber := Source.MaxSequenceNumber; 387 MaxSessionCount := Source.MaxSessionCount; 388 RemoteBufferSize := Source.RemoteBufferSize; 389 RemoteBufferUsed := Source.RemoteBufferUsed; 445 RemoteBuffer.Assign(Source.RemoteBuffer); 390 446 WrongSequenceCount := Source.WrongSequenceCount; 391 447 RetransmitTimeout := Source.RetransmitTimeout; … … 396 452 OnAfterRequest := Source.OnAfterRequest; 397 453 OnDebugLog := Source.OnDebugLog; 454 Sessions.Assign(Source.Sessions); 398 455 Active := Source.Active; 399 456 end; … … 431 488 Lock.Acquire; 432 489 Session.SequenceNumber := GetSequenceNumber; 433 while Count >= Parent.MaxSessionCount do490 while Count >= MaxSessionCount do 434 491 begin 435 492 try … … 474 531 inherited Create; 475 532 Lock := TCriticalSection.Create; 533 MaxSessionCount := 100; 534 MaxSequenceNumber := 127; 476 535 end; 477 536 … … 491 550 end; 492 551 552 procedure TDeviceProtocolSessionList.Assign(Source: TListObject); 553 begin 554 MaxSequenceNumber := TDeviceProtocolSessionList(Source).MaxSequenceNumber; 555 MaxSessionCount := TDeviceProtocolSessionList(Source).MaxSessionCount; 556 SequenceNumber := TDeviceProtocolSessionList(Source).SequenceNumber; 557 558 inherited; 559 end; 560 493 561 function TDeviceProtocolSessionList.GetSequenceNumber: Integer; 494 562 begin 495 Inc(SequenceNumber); 496 if SequenceNumber > Parent.MaxSequenceNumber then 497 SequenceNumber := 0; 498 Result := SequenceNumber; 563 try 564 //Lock.Acquire; 565 Inc(SequenceNumber); 566 if SequenceNumber > MaxSequenceNumber then 567 SequenceNumber := 0; 568 Result := SequenceNumber; 569 finally 570 //Lock.Release; 571 end; 499 572 end; 500 573 … … 514 587 while I < Sessions.Count do begin 515 588 Session := TDeviceProtocolSession(Sessions[I]); 516 with TDeviceProtocolSession(Sessions[I]) do begin 589 with Session do 590 if Enabled then begin 517 591 try 518 592 Session.Lock.Acquire;
Note:
See TracChangeset
for help on using the changeset viewer.