Skip to content

Commit e273f70

Browse files
authored
Fix the deadlock for pause/cancel (#596)
1 parent 19a2454 commit e273f70

File tree

3 files changed

+9
-10
lines changed

3 files changed

+9
-10
lines changed

include/aws/s3/private/s3_meta_request_impl.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ struct aws_s3_meta_request {
195195
/* If the buffer pool optimized for the specific size or not. */
196196
bool buffer_pool_optimized;
197197

198+
/* Track the number of requests being prepared for this meta request. */
199+
struct aws_atomic_var num_request_being_prepared;
200+
198201
struct {
199202
struct aws_mutex lock;
200203

@@ -278,9 +281,6 @@ struct aws_s3_meta_request {
278281
/* True if this meta request is currently in the client's list. */
279282
bool scheduled;
280283

281-
/* Track the number of requests being prepared for this meta request. */
282-
size_t num_request_being_prepared;
283-
284284
} client_process_work_threaded_data;
285285

286286
/* Anything in this structure should only ever be accessed by the meta-request from its io_event_loop thread. */

source/s3_client.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1906,8 +1906,9 @@ static bool s_s3_client_should_update_meta_request(
19061906
return false;
19071907
}
19081908

1909-
if (meta_request->client_process_work_threaded_data.num_request_being_prepared >=
1910-
aws_s3_client_get_max_active_connections(client, meta_request)) {
1909+
/* This is not 100% thread safe, but prepare a bit more for the meta request level won't actually hurt. */
1910+
size_t specific_request_being_prepared = aws_atomic_load_int(&meta_request->num_request_being_prepared);
1911+
if (specific_request_being_prepared >= aws_s3_client_get_max_active_connections(client, meta_request)) {
19111912
/* Don't prepare more than it's allowed for the meta request */
19121913
return false;
19131914
}
@@ -2125,7 +2126,7 @@ void aws_s3_client_update_meta_requests_threaded(struct aws_s3_client *client) {
21252126
request->tracked_by_client = true;
21262127

21272128
++client->threaded_data.num_requests_being_prepared;
2128-
++meta_request->client_process_work_threaded_data.num_request_being_prepared;
2129+
aws_atomic_fetch_add(&meta_request->num_request_being_prepared, 1);
21292130

21302131
num_requests_in_flight =
21312132
(uint32_t)aws_atomic_fetch_add(&client->stats.num_requests_in_flight, 1) + 1;
@@ -2192,6 +2193,7 @@ static void s_s3_client_prepare_callback_queue_request(
21922193
request = aws_s3_request_release(request);
21932194
}
21942195

2196+
aws_atomic_fetch_sub(&meta_request->num_request_being_prepared, 1);
21952197
/* BEGIN CRITICAL SECTION */
21962198
{
21972199
aws_s3_client_lock_synced_data(client);
@@ -2223,8 +2225,6 @@ void aws_s3_client_update_connections_threaded(struct aws_s3_client *client) {
22232225
struct aws_s3_request *request = aws_s3_client_dequeue_request_threaded(client);
22242226
struct aws_s3_meta_request *meta_request = request->meta_request;
22252227
const uint32_t max_active_connections = aws_s3_client_get_max_active_connections(client, meta_request);
2226-
/* As the request removed from the queue. Decrement the preparing track */
2227-
--meta_request->client_process_work_threaded_data.num_request_being_prepared;
22282228
if (request->is_noop) {
22292229
/* If request is no-op, finishes and cleans up the request */
22302230
s_s3_client_meta_request_finished_request(client, meta_request, request, AWS_ERROR_SUCCESS);
@@ -2250,8 +2250,6 @@ void aws_s3_client_update_connections_threaded(struct aws_s3_client *client) {
22502250
} else {
22512251
/* Push the request into the left-over list to be used in a future call of this function. */
22522252
aws_linked_list_push_back(&left_over_requests, &request->node);
2253-
/* Increment the count as we put it back to the queue. */
2254-
++meta_request->client_process_work_threaded_data.num_request_being_prepared;
22552253
}
22562254
client_max_active_connections = aws_s3_client_get_max_active_connections(client, NULL);
22572255
num_requests_network_io = s_s3_client_get_num_requests_network_io(client, AWS_S3_META_REQUEST_TYPE_MAX);

source/s3_meta_request.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ int aws_s3_meta_request_init_base(
200200
/* Set up reference count. */
201201
aws_ref_count_init(&meta_request->ref_count, meta_request, s_s3_meta_request_destroy);
202202
aws_atomic_init_int(&meta_request->num_requests_network, 0);
203+
aws_atomic_init_int(&meta_request->num_request_being_prepared, 0);
203204
aws_linked_list_init(&meta_request->synced_data.cancellable_http_streams_list);
204205
aws_linked_list_init(&meta_request->synced_data.pending_buffer_futures);
205206

0 commit comments

Comments
 (0)