@@ -268,6 +268,72 @@ static int s_test_s3_buffer_pool_reserve_over_limit(struct aws_allocator *alloca
268268};
269269AWS_TEST_CASE (test_s3_buffer_pool_reserve_over_limit , s_test_s3_buffer_pool_reserve_over_limit )
270270
271+ /* test that one big ticket release can complete several pending reserves*/
272+ static int s_test_s3_buffer_pool_reserve_over_limit_multi (struct aws_allocator * allocator , void * ctx ) {
273+ (void )allocator ;
274+ (void )ctx ;
275+
276+ struct aws_s3_buffer_pool * buffer_pool = aws_s3_default_buffer_pool_new (
277+ allocator , (struct aws_s3_buffer_pool_config ){.part_size = MB_TO_BYTES (8 ), .memory_limit = GB_TO_BYTES (1 )});
278+
279+ struct aws_s3_buffer_ticket * tickets [109 ];
280+ struct aws_future_s3_buffer_ticket * ticket_futures [109 ];
281+
282+ ticket_futures [0 ] = aws_s3_default_buffer_pool_reserve (
283+ buffer_pool , (struct aws_s3_buffer_pool_reserve_meta ){.size = MB_TO_BYTES (32 )});
284+ ASSERT_TRUE (aws_future_s3_buffer_ticket_is_done (ticket_futures [0 ]));
285+ ASSERT_INT_EQUALS (aws_future_s3_buffer_ticket_get_error (ticket_futures [0 ]), AWS_OP_SUCCESS );
286+ tickets [0 ] = aws_future_s3_buffer_ticket_get_result_by_move (ticket_futures [0 ]);
287+ struct aws_byte_buf buf = aws_s3_buffer_ticket_claim (tickets [0 ]);
288+ ASSERT_NOT_NULL (buf .buffer );
289+
290+ for (size_t i = 1 ; i < 109 ; ++ i ) {
291+ ticket_futures [i ] = aws_s3_default_buffer_pool_reserve (
292+ buffer_pool , (struct aws_s3_buffer_pool_reserve_meta ){.size = MB_TO_BYTES (8 )});
293+ ASSERT_TRUE (aws_future_s3_buffer_ticket_is_done (ticket_futures [i ]));
294+ ASSERT_INT_EQUALS (aws_future_s3_buffer_ticket_get_error (ticket_futures [i ]), AWS_OP_SUCCESS );
295+ tickets [i ] = aws_future_s3_buffer_ticket_get_result_by_move (ticket_futures [i ]);
296+ struct aws_byte_buf buf = aws_s3_buffer_ticket_claim (tickets [i ]);
297+ ASSERT_NOT_NULL (buf .buffer );
298+ }
299+
300+ struct aws_future_s3_buffer_ticket * over_future = aws_s3_default_buffer_pool_reserve (
301+ buffer_pool , (struct aws_s3_buffer_pool_reserve_meta ){.size = MB_TO_BYTES (8 )});
302+
303+ ASSERT_FALSE (aws_future_s3_buffer_ticket_is_done (over_future ));
304+ struct s_reserve_state state = {.future = over_future };
305+ aws_future_s3_buffer_ticket_register_callback (over_future , s_on_pool_buffer_reserved , & state );
306+
307+ struct aws_future_s3_buffer_ticket * over_future2 = aws_s3_default_buffer_pool_reserve (
308+ buffer_pool , (struct aws_s3_buffer_pool_reserve_meta ){.size = MB_TO_BYTES (8 )});
309+
310+ ASSERT_FALSE (aws_future_s3_buffer_ticket_is_done (over_future2 ));
311+ struct s_reserve_state state2 = {.future = over_future2 };
312+ aws_future_s3_buffer_ticket_register_callback (over_future2 , s_on_pool_buffer_reserved , & state2 );
313+
314+ /* Release big ticket */
315+ aws_s3_buffer_ticket_release (tickets [0 ]);
316+ aws_future_s3_buffer_ticket_release (ticket_futures [0 ]);
317+
318+ ASSERT_TRUE (aws_future_s3_buffer_ticket_is_done (over_future1 ));
319+ ASSERT_TRUE (aws_future_s3_buffer_ticket_is_done (over_future2 ));
320+
321+ for (size_t i = 1 ; i < 109 ; ++ i ) {
322+ aws_s3_buffer_ticket_release (tickets [i ]);
323+ aws_future_s3_buffer_ticket_release (ticket_futures [i ]);
324+ }
325+
326+ ASSERT_NOT_NULL (state .ticket );
327+
328+ aws_s3_buffer_ticket_release (state .ticket );
329+ aws_future_s3_buffer_ticket_release (over_future );
330+
331+ aws_s3_default_buffer_pool_destroy (buffer_pool );
332+
333+ return 0 ;
334+ };
335+ AWS_TEST_CASE (test_s3_buffer_pool_reserve_over_limit_multi , s_test_s3_buffer_pool_reserve_over_limit_multi )
336+
271337static void s_on_pool_buffer_reserved_instant_release (void * user_data ) {
272338 struct s_reserve_state * state = user_data ;
273339
0 commit comments