Fix async upgrade inside cork

This commit is contained in:
Alex Hultman
2023-04-15 21:28:30 +02:00
parent cc22680117
commit c5de72c9be
2 changed files with 18 additions and 1 deletions
+5
View File
@@ -135,6 +135,11 @@ protected:
getLoopData()->corkedSocket = this; getLoopData()->corkedSocket = this;
} }
/* Returns the corked socket or nullptr */
void *corkedSocket() {
return getLoopData()->corkedSocket;
}
/* Returns wheter we are corked or not */ /* Returns wheter we are corked or not */
bool isCorked() { bool isCorked() {
return getLoopData()->corkedSocket == this; return getLoopData()->corkedSocket == this;
+13 -1
View File
@@ -497,8 +497,20 @@ public:
Super::cork(); Super::cork();
handler(); handler();
/* The only way we could possibly have changed the corked socket during handler call, would be if
* the HTTP socket was upgraded to WebSocket and caused a realloc. Because of this we cannot use "this"
* from here downwards. The corking is done with corkUnchecked() in upgrade. It steals cork. */
auto *newCorkedSocket = Super::corkedSocket();
/* Timeout on uncork failure, since most writes will succeed while corked */ /* Timeout on uncork failure, since most writes will succeed while corked */
auto [written, failed] = Super::uncork(); auto [written, failed] = static_cast<Super *>(newCorkedSocket)->uncork();
/* If we are no longer an HTTP socket then early return the new "this".
* We don't want to even overwrite timeout as it is set in upgrade already. */
if (this != newCorkedSocket) {
return static_cast<HttpResponse *>(newCorkedSocket);
}
if (failed) { if (failed) {
/* For now we only have one single timeout so let's use it */ /* For now we only have one single timeout so let's use it */
/* This behavior should equal the behavior in HttpContext when uncorking fails */ /* This behavior should equal the behavior in HttpContext when uncorking fails */