@@ -1791,6 +1791,109 @@ static bool s_s3_client_should_update_meta_request(
17911791 return true;
17921792}
17931793
1794+ struct aws_s3_reserve_memory_payload {
1795+ struct aws_allocator * allocator ;
1796+ struct aws_s3_request * request ;
1797+ struct aws_future_s3_buffer_ticket * buffer_future ;
1798+ aws_s3_meta_request_prepare_request_callback_fn * callback ;
1799+ void * user_data ;
1800+ };
1801+
1802+ static void s_s3_prepare_acquire_mem_callback_and_destroy (
1803+ struct aws_s3_reserve_memory_payload * payload ,
1804+ int error_code ) {
1805+ AWS_PRECONDITION (payload );
1806+ AWS_PRECONDITION (payload -> request );
1807+
1808+ struct aws_s3_meta_request * meta_request = payload -> request -> meta_request ;
1809+ AWS_PRECONDITION (meta_request );
1810+
1811+ ++ payload -> request -> num_times_prepared ;
1812+
1813+ if (error_code ) {
1814+ AWS_LOGF_ERROR (
1815+ AWS_LS_S3_META_REQUEST ,
1816+ "id=%p Could not prepare request %p due to error %d (%s)." ,
1817+ (void * )meta_request ,
1818+ (void * )payload -> request ,
1819+ error_code ,
1820+ aws_error_str (error_code ));
1821+
1822+ /* BEGIN CRITICAL SECTION */
1823+ aws_s3_meta_request_lock_synced_data (meta_request );
1824+ aws_s3_meta_request_set_fail_synced (meta_request , payload -> request , error_code );
1825+ aws_s3_meta_request_unlock_synced_data (meta_request );
1826+ /* END CRITICAL SECTION */
1827+ }
1828+
1829+ if (payload -> callback != NULL ) {
1830+ payload -> callback (meta_request , payload -> request , error_code , payload -> user_data );
1831+ }
1832+
1833+ aws_future_s3_buffer_ticket_release (payload -> buffer_future );
1834+ aws_mem_release (payload -> allocator , payload );
1835+ }
1836+
1837+ static void s_on_pool_buffer_reserved (void * user_data ) {
1838+ struct aws_s3_reserve_memory_payload * payload = user_data ;
1839+ AWS_PRECONDITION (payload );
1840+
1841+ struct aws_s3_request * request = payload -> request ;
1842+ AWS_PRECONDITION (request );
1843+
1844+ struct aws_s3_meta_request * meta_request = request -> meta_request ;
1845+ AWS_PRECONDITION (meta_request );
1846+
1847+ struct aws_future_s3_buffer_ticket * future_ticket = payload -> buffer_future ;
1848+
1849+ int error_code = aws_future_s3_buffer_ticket_get_error (future_ticket );
1850+ if (error_code != AWS_ERROR_SUCCESS ) {
1851+ AWS_LOGF_ERROR (
1852+ AWS_LS_S3_META_REQUEST ,
1853+ "id=%p Could not allocate buffer for request with tag %d for the meta request." ,
1854+ (void * )meta_request ,
1855+ request -> request_tag );
1856+
1857+ s_s3_prepare_acquire_mem_callback_and_destroy (payload , AWS_ERROR_S3_BUFFER_ALLOCATION_FAILED );
1858+ return ;
1859+ }
1860+
1861+ request -> ticket = aws_future_s3_buffer_ticket_get_result_by_move (future_ticket );
1862+
1863+ aws_future_s3_buffer_ticket_release (payload -> buffer_future );
1864+ aws_mem_release (payload -> allocator , payload );
1865+
1866+ aws_s3_meta_request_prepare_request (request -> meta_request ,
1867+ request , payload -> callback , payload -> user_data );
1868+ return ;
1869+ }
1870+
1871+ void s_acquire_mem_and_prepare_request (struct aws_s3_client * client ,
1872+ struct aws_s3_request * request ,
1873+ aws_s3_meta_request_prepare_request_callback_fn * callback ,
1874+ void * user_data ) {
1875+
1876+ if (request -> ticket == NULL && request -> should_allocate_buffer_from_pool ) {
1877+ struct aws_allocator * allocator = request -> allocator ;
1878+ struct aws_s3_meta_request * meta_request = request -> meta_request ;
1879+ struct aws_s3_buffer_pool_reserve_meta meta = {
1880+ .client = client , .meta_request = meta_request , .size = meta_request -> part_size };
1881+
1882+ struct aws_s3_reserve_memory_payload * payload = aws_mem_calloc (allocator , 1 , sizeof (struct aws_s3_reserve_memory_payload ));
1883+
1884+ payload -> allocator = allocator ;
1885+ payload -> request = request ;
1886+ payload -> callback = callback ;
1887+ payload -> user_data = user_data ;
1888+ payload -> buffer_future = aws_s3_buffer_pool_reserve (request -> meta_request -> client -> buffer_pool , meta );
1889+
1890+ aws_future_s3_buffer_ticket_register_callback (payload -> buffer_future , s_on_pool_buffer_reserved , payload );
1891+ return ;
1892+ }
1893+
1894+ aws_s3_meta_request_prepare_request (request -> meta_request , request , callback , user_data );
1895+ }
1896+
17941897void aws_s3_client_update_meta_requests_threaded (struct aws_s3_client * client ) {
17951898 AWS_PRECONDITION (client );
17961899
@@ -1835,9 +1938,6 @@ void aws_s3_client_update_meta_requests_threaded(struct aws_s3_client *client) {
18351938 struct aws_s3_request * request = NULL ;
18361939
18371940 /* Try to grab the next request from the meta request. */
1838- /* TODO: should we bail out if request fails to update due to mem or
1839- * continue going and hopping that following reqs can fit into mem?
1840- * check if avail space is at least part size? */
18411941 bool work_remaining = aws_s3_meta_request_update (meta_request , pass_flags [pass_index ], & request );
18421942
18431943 if (work_remaining ) {
@@ -1856,8 +1956,8 @@ void aws_s3_client_update_meta_requests_threaded(struct aws_s3_client *client) {
18561956 num_requests_in_flight =
18571957 (uint32_t )aws_atomic_fetch_add (& client -> stats .num_requests_in_flight , 1 ) + 1 ;
18581958
1859- aws_s3_meta_request_prepare_request (
1860- meta_request , request , s_s3_client_prepare_callback_queue_request , client );
1959+ s_acquire_mem_and_prepare_request (
1960+ client , request , s_s3_client_prepare_callback_queue_request , client );
18611961 }
18621962 } else {
18631963 s_s3_client_remove_meta_request_threaded (client , meta_request );
0 commit comments