Skip to content

Commit 23f2437

Browse files
committed
Ensure tcp server is cleaned up in failure cases
1 parent f62639f commit 23f2437

2 files changed

Lines changed: 55 additions & 33 deletions

File tree

src/hx/libs/asys/libuv/net/LibuvTcpServer.cpp

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <hxcpp.h>
12
#include "LibuvTcpServer.h"
23
#include "LibuvTcpSocket.h"
34
#include "NetUtils.h"
@@ -12,11 +13,9 @@ namespace
1213

1314
if (status < 0)
1415
{
15-
auto request = std::unique_ptr<hx::asys::libuv::BaseRequest>();
16-
while (nullptr != (request = server->connections.tryDequeue()))
17-
{
18-
Dynamic(request->cbFailure.rooted)(hx::asys::libuv::uv_err_to_enum(status));
19-
}
16+
server->status = status;
17+
18+
uv_close(reinterpret_cast<uv_handle_t*>(stream), hx::asys::libuv::net::LibuvTcpServerImpl::cleanup);
2019
}
2120
else
2221
{
@@ -33,32 +32,32 @@ namespace
3332
return;
3433
}
3534

36-
if ((result = uv_tcp_keepalive(socket.get(), server->keepAlive > 0, hx::asys::libuv::net::KEEP_ALIVE_VALUE)) < 0)
37-
{
38-
Dynamic(request->cbFailure.rooted)(hx::asys::libuv::uv_err_to_enum(result));
35+
// if ((result = uv_tcp_keepalive(socket.get(), server->keepAlive > 0, hx::asys::libuv::net::KEEP_ALIVE_VALUE)) < 0)
36+
// {
37+
// Dynamic(request->cbFailure.rooted)(hx::asys::libuv::uv_err_to_enum(result));
3938

40-
return;
41-
}
39+
// return;
40+
// }
4241

43-
if (server->sendBufferSize > 0)
44-
{
45-
if ((result = uv_send_buffer_size(reinterpret_cast<uv_handle_t*>(socket.get()), &server->sendBufferSize)) < 0)
46-
{
47-
Dynamic(request->cbFailure.rooted)(hx::asys::libuv::uv_err_to_enum(result));
42+
// if (server->sendBufferSize > 0)
43+
// {
44+
// if ((result = uv_send_buffer_size(reinterpret_cast<uv_handle_t*>(socket.get()), &server->sendBufferSize)) < 0)
45+
// {
46+
// Dynamic(request->cbFailure.rooted)(hx::asys::libuv::uv_err_to_enum(result));
4847

49-
return;
50-
}
51-
}
48+
// return;
49+
// }
50+
// }
5251

53-
if (server->recvBufferSize > 0)
54-
{
55-
if ((result = uv_recv_buffer_size(reinterpret_cast<uv_handle_t*>(socket.get()), &server->sendBufferSize)) < 0)
56-
{
57-
Dynamic(request->cbFailure.rooted)(hx::asys::libuv::uv_err_to_enum(result));
52+
// if (server->recvBufferSize > 0)
53+
// {
54+
// if ((result = uv_recv_buffer_size(reinterpret_cast<uv_handle_t*>(socket.get()), &server->sendBufferSize)) < 0)
55+
// {
56+
// Dynamic(request->cbFailure.rooted)(hx::asys::libuv::uv_err_to_enum(result));
5857

59-
return;
60-
}
61-
}
58+
// return;
59+
// }
60+
// }
6261

6362
if ((result = uv_accept(reinterpret_cast<uv_stream_t*>(&server->tcp), reinterpret_cast<uv_stream_t*>(socket.get()))) < 0)
6463
{
@@ -106,7 +105,7 @@ namespace
106105
}
107106
}
108107

109-
auto server = std::make_unique<hx::asys::libuv::net::LibuvTcpServerImpl>(ctx->uvLoop, keepAlive, sendBufferSize, recvBufferSize);
108+
auto server = std::make_unique<hx::asys::libuv::net::LibuvTcpServerImpl>(cbSuccess, cbFailure, ctx->uvLoop, keepAlive, sendBufferSize, recvBufferSize);
110109
auto result = 0;
111110

112111
if ((result = uv_tcp_init(ctx->uvLoop, &server->tcp)) < 0)
@@ -118,14 +117,20 @@ namespace
118117

119118
if ((result = uv_tcp_bind(&server->tcp, address, 0)) < 0)
120119
{
121-
cbFailure(hx::asys::libuv::uv_err_to_enum(result));
120+
server->status = result;
121+
122+
uv_close(reinterpret_cast<uv_handle_t*>(&server.release()->tcp), hx::asys::libuv::net::LibuvTcpServerImpl::cleanup);
122123

123124
return;
124125
}
125126

126127
if ((result = uv_listen(reinterpret_cast<uv_stream_t*>(&server->tcp), backlog, onConnection)) < 0)
127128
{
128-
cbFailure(hx::asys::libuv::uv_err_to_enum(result));
129+
server->status = result;
130+
131+
uv_close(reinterpret_cast<uv_handle_t*>(&server.release()->tcp), hx::asys::libuv::net::LibuvTcpServerImpl::cleanup);
132+
133+
return;
129134
}
130135
else
131136
{
@@ -163,15 +168,27 @@ std::unique_ptr<hx::asys::libuv::BaseRequest> hx::asys::libuv::net::ConnectionQu
163168
return root;
164169
}
165170

166-
hx::asys::libuv::net::LibuvTcpServerImpl::LibuvTcpServerImpl(uv_loop_t* _loop, int keepAlive, int sendBufferSize, int recvBufferSize)
167-
: loop(_loop)
171+
hx::asys::libuv::net::LibuvTcpServerImpl::LibuvTcpServerImpl(Dynamic cbSuccess, Dynamic cbFailure, uv_loop_t* _loop, const int keepAlive, const int sendBufferSize, const int recvBufferSize)
172+
: hx::asys::libuv::BaseRequest(cbSuccess, cbFailure)
173+
, loop(_loop)
168174
, keepAlive(keepAlive)
169175
, sendBufferSize(sendBufferSize)
170176
, recvBufferSize(recvBufferSize)
177+
, status(0)
178+
, connections()
171179
{
172180
tcp.data = this;
173181
}
174182

183+
void hx::asys::libuv::net::LibuvTcpServerImpl::cleanup(uv_handle_t* handle)
184+
{
185+
auto spData = std::unique_ptr<LibuvTcpServerImpl>(reinterpret_cast<LibuvTcpServerImpl*>(handle->data));
186+
auto cbFailure = Dynamic(spData->cbFailure.rooted);
187+
188+
cbFailure(hx::asys::libuv::uv_err_to_enum(spData->status));
189+
190+
}
191+
175192
hx::asys::libuv::net::LibuvTcpServer::LibuvTcpServer(LibuvTcpServerImpl* _server) : server(_server)
176193
{
177194
HX_OBJ_WB_NEW_MARKED_OBJECT(this);

src/hx/libs/asys/libuv/net/LibuvTcpServer.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#pragma once
2+
13
#include <hxcpp.h>
24
#include <memory>
35
#include <deque>
@@ -21,7 +23,7 @@ namespace hx::asys::libuv::net
2123
std::unique_ptr<hx::asys::libuv::BaseRequest> tryDequeue();
2224
};
2325

24-
class LibuvTcpServerImpl final
26+
class LibuvTcpServerImpl final : public BaseRequest
2527
{
2628
public:
2729
uv_tcp_t tcp;
@@ -30,8 +32,11 @@ namespace hx::asys::libuv::net
3032
int keepAlive;
3133
int sendBufferSize;
3234
int recvBufferSize;
35+
int status;
36+
37+
LibuvTcpServerImpl(Dynamic cbSuccess, Dynamic cbFailure, uv_loop_t* _loop, int keepAlive, int sendBufferSize, int recvBufferSize);
3338

34-
LibuvTcpServerImpl(uv_loop_t* _loop, int keepAlive, int sendBufferSize, int recvBufferSize);
39+
static void cleanup(uv_handle_t* handle);
3540
};
3641

3742
class LibuvTcpServer final : public hx::asys::net::TcpServer_obj

0 commit comments

Comments
 (0)