@@ -2209,8 +2209,11 @@ void Session::StreamDataBlocked(stream_id id) {
2209
2209
IncrementStat (&SessionStats::block_count);
2210
2210
2211
2211
BaseObjectPtr<Stream> stream = FindStream (id);
2212
- if (stream)
2212
+ if (stream) {
2213
2213
stream->OnBlocked ();
2214
+ } else {
2215
+ Debug (this , " Stream %" PRId64 " not found to block" , id);
2216
+ }
2214
2217
}
2215
2218
2216
2219
void Session::IncrementConnectionCloseAttempts () {
@@ -3268,26 +3271,34 @@ bool Session::Application::SendPendingData() {
3268
3271
uint8_t * pos = nullptr ;
3269
3272
size_t packets_sent = 0 ;
3270
3273
int err;
3274
+ std::vector<stream_id> blocking;
3275
+ bool ret = false ;
3276
+ BaseObjectPtr<Stream> stream;
3271
3277
3272
3278
Debug (session (), " Start sending pending data" );
3273
3279
for (;;) {
3274
- ssize_t ndatalen;
3275
3280
StreamData stream_data;
3281
+ ssize_t ndatalen = 0 ;
3276
3282
err = GetStreamData (&stream_data);
3277
3283
if (err < 0 ) {
3278
3284
session ()->set_last_error (kQuicInternalError );
3279
- return false ;
3285
+ goto end ;
3280
3286
}
3281
3287
3282
3288
// If the packet was sent previously, then packet will have been reset.
3283
3289
if (!pos) {
3284
3290
packet = CreateStreamDataPacket ();
3291
+ if (!packet) {
3292
+ Debug (session (), " Failed to create packet for stream data" );
3293
+ session ()->set_last_error (kQuicInternalError );
3294
+ goto end;
3295
+ }
3285
3296
pos = packet->data ();
3286
3297
}
3287
3298
3288
3299
// If stream_data.id is -1, then we're not serializing any data for any
3289
3300
// specific stream. We still need to process QUIC session packets tho.
3290
- if (stream_data.id > - 1 ) {
3301
+ if (stream_data.id >= 0 ) {
3291
3302
Debug (session (), " Serializing packets for stream id %" PRId64,
3292
3303
stream_data.id );
3293
3304
packet->AddRetained (stream_data.stream ->GetOutboundSource ());
@@ -3322,10 +3333,11 @@ bool Session::Application::SendPendingData() {
3322
3333
// CONNECTION_CLOSE since even those require a
3323
3334
// packet number.
3324
3335
session ()->Close (Session::SessionCloseFlags::SILENT);
3325
- return false ;
3336
+ goto end ;
3326
3337
case NGTCP2_ERR_STREAM_DATA_BLOCKED:
3327
- Debug (session (), " Stream %lld blocked" , stream_data.id );
3338
+ Debug (session (), " Stream %lld blocked session data left %lld " , stream_data.id , session ()-> max_data_left () );
3328
3339
session ()->StreamDataBlocked (stream_data.id );
3340
+ blocking.push_back (stream_data.id );
3329
3341
if (session ()->max_data_left () == 0 ) {
3330
3342
if (stream_data.id >= 0 ) {
3331
3343
Debug (session (), " Resuming %llu after block" , stream_data.id );
@@ -3344,6 +3356,7 @@ bool Session::Application::SendPendingData() {
3344
3356
CHECK_LE (ndatalen, 0 );
3345
3357
continue ;
3346
3358
case NGTCP2_ERR_STREAM_NOT_FOUND:
3359
+ Debug (session (), " Stream %lld no found" , stream_data.id );
3347
3360
continue ;
3348
3361
case NGTCP2_ERR_WRITE_MORE:
3349
3362
CHECK_GT (ndatalen, 0 );
@@ -3354,7 +3367,7 @@ bool Session::Application::SendPendingData() {
3354
3367
if (nwrite != 0 ){ // -ve response i.e error
3355
3368
packet.reset ();
3356
3369
session ()->set_last_error (kQuicInternalError );
3357
- return false ;
3370
+ goto end ;
3358
3371
}
3359
3372
3360
3373
// 0 bytes in this sending operation
@@ -3368,9 +3381,10 @@ bool Session::Application::SendPendingData() {
3368
3381
Debug (session (), " Congestion limited, but %" PRIu64 " bytes pending" ,
3369
3382
packet->length ());
3370
3383
if (!session ()->SendPacket (std::move (packet), path))
3371
- return false ;
3384
+ goto end ;
3372
3385
}
3373
- return true ;
3386
+ ret = true ;
3387
+ goto end;
3374
3388
}
3375
3389
3376
3390
pos += nwrite;
@@ -3384,16 +3398,27 @@ bool Session::Application::SendPendingData() {
3384
3398
Debug (session (), " Sending %" PRIu64 " bytes in serialized packet" , nwrite);
3385
3399
if (!session ()->SendPacket (std::move (packet), path)) {
3386
3400
Debug (session (), " -- Failed to send packet" );
3387
- return false ;
3401
+ goto end ;
3388
3402
}
3389
3403
pos = nullptr ;
3390
3404
if (++packets_sent == kMaxPackets ) {
3391
3405
Debug (session (), " -- Max packets sent" );
3392
3406
break ;
3393
3407
}
3394
3408
Debug (session (), " -- Looping" );
3409
+ } // end for
3410
+
3411
+
3412
+ ret = true ;
3413
+ end:
3414
+ for (stream_id id : blocking) {
3415
+ stream = session ()->FindStream (id);
3416
+ if (stream) {
3417
+ stream->Unblock ();
3418
+ }
3395
3419
}
3396
- return true ;
3420
+
3421
+ return ret;
3397
3422
}
3398
3423
3399
3424
void Session::Application::StreamClose (
@@ -3576,13 +3601,24 @@ bool DefaultApplication::ReceiveStreamData(
3576
3601
}
3577
3602
3578
3603
int DefaultApplication::GetStreamData (StreamData* stream_data) {
3604
+ if (stream_queue_.IsEmpty ()) {
3605
+ stream_data->id = -1 ;
3606
+ return 0 ;
3607
+ }
3608
+
3579
3609
Stream* stream = stream_queue_.PopFront ();
3580
- stream_data->stream .reset (stream);
3581
3610
if (stream == nullptr ) {
3582
3611
stream_data->id = -1 ;
3583
3612
return 0 ;
3584
3613
}
3585
3614
CHECK (!stream->is_destroyed ());
3615
+ stream_data->stream .reset (stream);
3616
+
3617
+ if (stream->IsBlocked ()){
3618
+ stream_data->id = -1 ;
3619
+ return 0 ;
3620
+ }
3621
+
3586
3622
stream_data->id = stream->id ();
3587
3623
auto next = [&](
3588
3624
int status,
@@ -3600,7 +3636,6 @@ int DefaultApplication::GetStreamData(StreamData* stream_data) {
3600
3636
3601
3637
stream_data->count = count;
3602
3638
if (count > 0 ) {
3603
-
3604
3639
stream->Schedule (&stream_queue_);
3605
3640
stream_data->remaining = get_length (data, count);
3606
3641
} else {
0 commit comments