Skip to content

Commit df6a575

Browse files
committed
fix cancel s3crt request callback to not outlive request lifetime
1 parent 70c3d5c commit df6a575

File tree

6 files changed

+64
-20
lines changed

6 files changed

+64
-20
lines changed

generated/src/aws-cpp-sdk-s3-crt/include/aws/s3-crt/S3CrtClient.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8146,6 +8146,9 @@ class AWS_S3CRT_API S3CrtClient : public Aws::Client::AWSXMLClient, public Aws::
81468146
std::shared_ptr<Aws::Http::HttpResponse> response;
81478147
std::shared_ptr<Aws::Crt::Http::HttpRequest> crtHttpRequest;
81488148
Aws::UniquePtr<struct aws_s3_checksum_config> checksumConfig;
8149+
std::mutex requestLifetimeMutex;
8150+
std::condition_variable requestLifetimeCondition;
8151+
bool requestLifetimeShouldContinue = true;
81498152
};
81508153

81518154
Aws::Client::XmlOutcome GenerateXmlOutcome(const std::shared_ptr<Http::HttpResponse>& response) const;
@@ -8167,7 +8170,7 @@ class AWS_S3CRT_API S3CrtClient : public Aws::Client::AWSXMLClient, public Aws::
81678170
};
81688171

81698172
static void CrtClientShutdownCallback(void* data);
8170-
void CancelCrtRequestAsync(aws_s3_meta_request* meta_request) const;
8173+
void CancelCrtRequestAsync(aws_s3_meta_request* meta_request, S3CrtClient::CrtRequestCallbackUserData* userData) const;
81718174
static int S3CrtRequestHeadersCallback(aws_s3_meta_request* meta_request, const struct aws_http_headers* headers, int response_status,
81728175
void* user_data);
81738176
static int S3CrtRequestGetBodyCallback(struct aws_s3_meta_request* meta_request, const struct aws_byte_cursor* body, uint64_t range_start,

generated/src/aws-cpp-sdk-s3-crt/source/S3CrtClient.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -501,9 +501,17 @@ void S3CrtClient::CrtClientShutdownCallback(void* data) {
501501
wrappedData->clientShutdownSem->Release();
502502
}
503503

504-
void S3CrtClient::CancelCrtRequestAsync(aws_s3_meta_request* meta_request) const {
504+
void S3CrtClient::CancelCrtRequestAsync(aws_s3_meta_request* meta_request, S3CrtClient::CrtRequestCallbackUserData* userData) const {
505505
assert(meta_request);
506-
m_clientConfiguration.executor->Submit([meta_request]() { aws_s3_meta_request_cancel(meta_request); });
506+
userData->requestLifetimeShouldContinue = false;
507+
m_clientConfiguration.executor->Submit([meta_request, userData]() {
508+
{
509+
std::lock_guard<std::mutex> requestLifetimeLock{userData->requestLifetimeMutex};
510+
aws_s3_meta_request_cancel(meta_request);
511+
userData->requestLifetimeShouldContinue = true;
512+
}
513+
userData->requestLifetimeCondition.notify_all();
514+
});
507515
}
508516

509517
int S3CrtClient::S3CrtRequestHeadersCallback(struct aws_s3_meta_request* meta_request, const struct aws_http_headers* headers,
@@ -525,7 +533,7 @@ int S3CrtClient::S3CrtRequestHeadersCallback(struct aws_s3_meta_request* meta_re
525533
auto& shouldContinueFn = userData->originalRequest->GetContinueRequestHandler();
526534
const HttpRequest* httpRequest = userData->request ? userData->request.get() : nullptr;
527535
if (shouldContinueFn && !shouldContinueFn(httpRequest)) {
528-
userData->s3CrtClient->CancelCrtRequestAsync(meta_request);
536+
userData->s3CrtClient->CancelCrtRequestAsync(meta_request, userData);
529537
}
530538

531539
return AWS_OP_SUCCESS;
@@ -558,7 +566,7 @@ int S3CrtClient::S3CrtRequestGetBodyCallback(struct aws_s3_meta_request* meta_re
558566
auto& shouldContinueFn = userData->originalRequest->GetContinueRequestHandler();
559567
const HttpRequest* httpRequest = userData->request ? userData->request.get() : nullptr;
560568
if (shouldContinueFn && !shouldContinueFn(httpRequest)) {
561-
userData->s3CrtClient->CancelCrtRequestAsync(meta_request);
569+
userData->s3CrtClient->CancelCrtRequestAsync(meta_request, userData);
562570
}
563571

564572
return AWS_OP_SUCCESS;
@@ -580,7 +588,7 @@ void S3CrtClient::S3CrtRequestProgressCallback(struct aws_s3_meta_request* meta_
580588
auto& shouldContinueFn = userData->originalRequest->GetContinueRequestHandler();
581589
const HttpRequest* httpRequest = userData->request ? userData->request.get() : nullptr;
582590
if (shouldContinueFn && !shouldContinueFn(httpRequest)) {
583-
userData->s3CrtClient->CancelCrtRequestAsync(meta_request);
591+
userData->s3CrtClient->CancelCrtRequestAsync(meta_request, userData);
584592
}
585593

586594
return;
@@ -643,6 +651,11 @@ void S3CrtClient::S3CrtRequestFinishCallback(struct aws_s3_meta_request* meta_re
643651
AWS_UNREFERENCED_PARAM(meta_request);
644652
auto* userData = static_cast<S3CrtClient::CrtRequestCallbackUserData*>(user_data);
645653

654+
{
655+
std::unique_lock<std::mutex> requestLifetimeLock{userData->requestLifetimeMutex};
656+
userData->requestLifetimeCondition.wait(requestLifetimeLock, [userData]() -> bool { return userData->requestLifetimeShouldContinue; });
657+
}
658+
646659
if (meta_request_result->error_code != AWS_ERROR_SUCCESS && meta_request_result->response_status == 0) {
647660
/* client side error */
648661
userData->response->SetClientErrorType(CoreErrors::NETWORK_CONNECTION);

tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/S3ClientHeader.vm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ namespace ${rootNamespace}
207207
std::shared_ptr<Aws::Http::HttpResponse> response;
208208
std::shared_ptr<Aws::Crt::Http::HttpRequest> crtHttpRequest;
209209
Aws::UniquePtr<struct aws_s3_checksum_config> checksumConfig;
210+
std::mutex requestLifetimeMutex;
211+
std::condition_variable requestLifetimeCondition;
212+
bool requestLifetimeShouldContinue = true;
210213
};
211214

212215
Aws::Client::XmlOutcome GenerateXmlOutcome(const std::shared_ptr<Http::HttpResponse>& response) const;
@@ -230,7 +233,7 @@ namespace ${rootNamespace}
230233
};
231234

232235
static void CrtClientShutdownCallback(void *data);
233-
void CancelCrtRequestAsync(aws_s3_meta_request *meta_request) const;
236+
void CancelCrtRequestAsync(aws_s3_meta_request *meta_request, S3CrtClient::CrtRequestCallbackUserData* userData) const;
234237
static int S3CrtRequestHeadersCallback(aws_s3_meta_request *meta_request, const struct aws_http_headers *headers, int response_status, void *user_data);
235238
static int S3CrtRequestGetBodyCallback(struct aws_s3_meta_request *meta_request, const struct aws_byte_cursor *body, uint64_t range_start, void *user_data);
236239
static void S3CrtRequestProgressCallback(struct aws_s3_meta_request *meta_request, const struct aws_s3_meta_request_progress *progress, void *user_data);

tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/SmithyS3ClientHeader.vm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ namespace ${rootNamespace}
231231
std::shared_ptr<Aws::Http::HttpResponse> response;
232232
std::shared_ptr<Aws::Crt::Http::HttpRequest> crtHttpRequest;
233233
Aws::UniquePtr<struct aws_s3_checksum_config> checksumConfig;
234+
std::mutex requestLifetimeMutex;
235+
std::condition_variable requestLifetimeCondition;
236+
bool requestLifetimeShouldContinue = true;
234237
};
235238

236239
Aws::Client::XmlOutcome GenerateXmlOutcome(const std::shared_ptr<Http::HttpResponse>& response) const;
@@ -250,7 +253,7 @@ namespace ${rootNamespace}
250253
};
251254

252255
static void CrtClientShutdownCallback(void *data);
253-
void CancelCrtRequestAsync(aws_s3_meta_request *meta_request) const;
256+
void CancelCrtRequestAsync(aws_s3_meta_request *meta_request, S3CrtClient::CrtRequestCallbackUserData* userData) const;
254257
static int S3CrtRequestHeadersCallback(aws_s3_meta_request *meta_request, const struct aws_http_headers *headers, int response_status, void *user_data);
255258
static int S3CrtRequestGetBodyCallback(struct aws_s3_meta_request *meta_request, const struct aws_byte_cursor *body, uint64_t range_start, void *user_data);
256259
static void S3CrtRequestProgressCallback(struct aws_s3_meta_request *meta_request, const struct aws_s3_meta_request_progress *progress, void *user_data);

tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/s3-crt/S3CrtSpecificOperations.vm

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,16 @@ void S3CrtClient::CrtClientShutdownCallback(void *data)
1111
wrappedData->clientShutdownSem->Release();
1212
}
1313

14-
void S3CrtClient::CancelCrtRequestAsync(aws_s3_meta_request *meta_request) const {
14+
void S3CrtClient::CancelCrtRequestAsync(aws_s3_meta_request *meta_request, S3CrtClient::CrtRequestCallbackUserData* userData) const {
1515
assert(meta_request);
16-
m_clientConfiguration.executor->Submit([meta_request]() {
17-
aws_s3_meta_request_cancel(meta_request);
16+
userData->requestLifetimeShouldContinue = false;
17+
m_clientConfiguration.executor->Submit([meta_request, userData]() {
18+
{
19+
std::lock_guard<std::mutex> requestLifetimeLock{userData->requestLifetimeMutex};
20+
aws_s3_meta_request_cancel(meta_request);
21+
userData->requestLifetimeShouldContinue = true;
22+
}
23+
userData->requestLifetimeCondition.notify_all();
1824
});
1925
}
2026

@@ -38,7 +44,7 @@ int S3CrtClient::S3CrtRequestHeadersCallback(struct aws_s3_meta_request *meta_re
3844
auto& shouldContinueFn = userData->originalRequest->GetContinueRequestHandler();
3945
const HttpRequest* httpRequest = userData->request ? userData->request.get() : nullptr;
4046
if (shouldContinueFn && !shouldContinueFn(httpRequest)) {
41-
userData->s3CrtClient->CancelCrtRequestAsync(meta_request);
47+
userData->s3CrtClient->CancelCrtRequestAsync(meta_request, userData);
4248
}
4349

4450
return AWS_OP_SUCCESS;
@@ -73,7 +79,7 @@ int S3CrtClient::S3CrtRequestGetBodyCallback(struct aws_s3_meta_request *meta_re
7379
auto& shouldContinueFn = userData->originalRequest->GetContinueRequestHandler();
7480
const HttpRequest* httpRequest = userData->request ? userData->request.get() : nullptr;
7581
if (shouldContinueFn && !shouldContinueFn(httpRequest)) {
76-
userData->s3CrtClient->CancelCrtRequestAsync(meta_request);
82+
userData->s3CrtClient->CancelCrtRequestAsync(meta_request, userData);
7783
}
7884

7985
return AWS_OP_SUCCESS;
@@ -95,7 +101,7 @@ void S3CrtClient::S3CrtRequestProgressCallback(struct aws_s3_meta_request *meta_
95101
auto& shouldContinueFn = userData->originalRequest->GetContinueRequestHandler();
96102
const HttpRequest* httpRequest = userData->request ? userData->request.get() : nullptr;
97103
if (shouldContinueFn && !shouldContinueFn(httpRequest)) {
98-
userData->s3CrtClient->CancelCrtRequestAsync(meta_request);
104+
userData->s3CrtClient->CancelCrtRequestAsync(meta_request, userData);
99105
}
100106

101107
return;
@@ -159,6 +165,11 @@ void S3CrtClient::S3CrtRequestFinishCallback(struct aws_s3_meta_request *meta_re
159165
AWS_UNREFERENCED_PARAM(meta_request);
160166
auto *userData = static_cast<S3CrtClient::CrtRequestCallbackUserData*>(user_data);
161167

168+
{
169+
std::unique_lock<std::mutex> requestLifetimeLock{userData->requestLifetimeMutex};
170+
userData->requestLifetimeCondition.wait(requestLifetimeLock, [userData]() -> bool { return userData->requestLifetimeShouldContinue; });
171+
}
172+
162173
if (meta_request_result->error_code != AWS_ERROR_SUCCESS && meta_request_result->response_status == 0) {
163174
/* client side error */
164175
userData->response->SetClientErrorType(CoreErrors::NETWORK_CONNECTION);

tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/s3-crt/SmithyS3CrtSpecificOperations.vm

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,16 @@ void S3CrtClient::CrtClientShutdownCallback(void *data)
1111
wrappedData->clientShutdownSem->Release();
1212
}
1313

14-
void S3CrtClient::CancelCrtRequestAsync(aws_s3_meta_request *meta_request) const {
14+
void S3CrtClient::CancelCrtRequestAsync(aws_s3_meta_request* meta_request, S3CrtClient::CrtRequestCallbackUserData* userData) const {
1515
assert(meta_request);
16-
m_clientConfiguration.executor->Submit([meta_request]() {
17-
aws_s3_meta_request_cancel(meta_request);
16+
userData->requestLifetimeShouldContinue = false;
17+
m_clientConfiguration.executor->Submit([meta_request, userData]() {
18+
{
19+
std::lock_guard<std::mutex> requestLifetimeLock{userData->requestLifetimeMutex};
20+
aws_s3_meta_request_cancel(meta_request);
21+
userData->requestLifetimeShouldContinue = true;
22+
}
23+
userData->requestLifetimeCondition.notify_all();
1824
});
1925
}
2026

@@ -38,7 +44,7 @@ int S3CrtClient::S3CrtRequestHeadersCallback(struct aws_s3_meta_request *meta_re
3844
auto& shouldContinueFn = userData->originalRequest->GetContinueRequestHandler();
3945
const HttpRequest* httpRequest = userData->request ? userData->request.get() : nullptr;
4046
if (shouldContinueFn && !shouldContinueFn(httpRequest)) {
41-
userData->s3CrtClient->CancelCrtRequestAsync(meta_request);
47+
userData->s3CrtClient->CancelCrtRequestAsync(meta_request, userData);
4248
}
4349

4450
return AWS_OP_SUCCESS;
@@ -73,7 +79,7 @@ int S3CrtClient::S3CrtRequestGetBodyCallback(struct aws_s3_meta_request *meta_re
7379
auto& shouldContinueFn = userData->originalRequest->GetContinueRequestHandler();
7480
const HttpRequest* httpRequest = userData->request ? userData->request.get() : nullptr;
7581
if (shouldContinueFn && !shouldContinueFn(httpRequest)) {
76-
userData->s3CrtClient->CancelCrtRequestAsync(meta_request);
82+
userData->s3CrtClient->CancelCrtRequestAsync(meta_request, userData);
7783
}
7884

7985
return AWS_OP_SUCCESS;
@@ -95,7 +101,7 @@ void S3CrtClient::S3CrtRequestProgressCallback(struct aws_s3_meta_request *meta_
95101
auto& shouldContinueFn = userData->originalRequest->GetContinueRequestHandler();
96102
const HttpRequest* httpRequest = userData->request ? userData->request.get() : nullptr;
97103
if (shouldContinueFn && !shouldContinueFn(httpRequest)) {
98-
userData->s3CrtClient->CancelCrtRequestAsync(meta_request);
104+
userData->s3CrtClient->CancelCrtRequestAsync(meta_request, userData);
99105
}
100106

101107
return;
@@ -159,6 +165,11 @@ void S3CrtClient::S3CrtRequestFinishCallback(struct aws_s3_meta_request *meta_re
159165
AWS_UNREFERENCED_PARAM(meta_request);
160166
auto *userData = static_cast<S3CrtClient::CrtRequestCallbackUserData*>(user_data);
161167

168+
{
169+
std::unique_lock<std::mutex> requestLifetimeLock{userData->requestLifetimeMutex};
170+
userData->requestLifetimeCondition.wait(requestLifetimeLock, [userData]() -> bool { return userData->requestLifetimeShouldContinue; });
171+
}
172+
162173
if (meta_request_result->error_code != AWS_ERROR_SUCCESS && meta_request_result->response_status == 0) {
163174
/* client side error */
164175
userData->response->SetClientErrorType(CoreErrors::NETWORK_CONNECTION);

0 commit comments

Comments
 (0)