-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
src: extracting OnConnection from pipe_wrap and tcp_wrap #7547
Changes from all commits
ad6dee3
a3b976e
34d5abc
564342d
623ad2e
458accc
ee0f2b9
5562c45
ee62109
579f48a
1437ec6
d0da4bc
1b3be60
e364ec4
e8ed621
7ce112a
c9ec24d
5ef85f9
ece2d31
73c956d
4feb84a
0a1ff38
85af1a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#include "connection_wrap.h" | ||
|
||
#include "env-inl.h" | ||
#include "env.h" | ||
#include "pipe_wrap.h" | ||
#include "stream_wrap.h" | ||
#include "tcp_wrap.h" | ||
#include "util.h" | ||
#include "util-inl.h" | ||
|
||
namespace node { | ||
|
||
using v8::Context; | ||
using v8::HandleScope; | ||
using v8::Integer; | ||
using v8::Local; | ||
using v8::Object; | ||
using v8::Value; | ||
|
||
|
||
template <typename WrapType, typename UVType> | ||
ConnectionWrap<WrapType, UVType>::ConnectionWrap(Environment* env, | ||
Local<Object> object, | ||
ProviderType provider, | ||
AsyncWrap* parent) | ||
: StreamWrap(env, | ||
object, | ||
reinterpret_cast<uv_stream_t*>(&handle_), | ||
provider, | ||
parent) {} | ||
|
||
|
||
template <typename WrapType, typename UVType> | ||
void ConnectionWrap<WrapType, UVType>::OnConnection(uv_stream_t* handle, | ||
int status) { | ||
WrapType* wrap_data = static_cast<WrapType*>(handle->data); | ||
CHECK_NE(wrap_data, nullptr); | ||
CHECK_EQ(&wrap_data->handle_, reinterpret_cast<UVType*>(handle)); | ||
|
||
Environment* env = wrap_data->env(); | ||
HandleScope handle_scope(env->isolate()); | ||
Context::Scope context_scope(env->context()); | ||
|
||
// We should not be getting this callback if someone has already called | ||
// uv_close() on the handle. | ||
CHECK_EQ(wrap_data->persistent().IsEmpty(), false); | ||
|
||
Local<Value> argv[] = { | ||
Integer::New(env->isolate(), status), | ||
Undefined(env->isolate()) | ||
}; | ||
|
||
if (status == 0) { | ||
// Instantiate the client javascript object and handle. | ||
Local<Object> client_obj = WrapType::Instantiate(env, wrap_data); | ||
|
||
// Unwrap the client javascript object. | ||
WrapType* wrap; | ||
ASSIGN_OR_RETURN_UNWRAP(&wrap, client_obj); | ||
uv_stream_t* client_handle = | ||
reinterpret_cast<uv_stream_t*>(&wrap->handle_); | ||
// uv_accept can fail if the new connection has already been closed, in | ||
// which case an EAGAIN (resource temporarily unavailable) will be | ||
// returned. | ||
if (uv_accept(handle, client_handle)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While you're here, can you add a comment explaining that uv_accept() can fail when the new connection is already closed again by the peer? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No problem, I'll add a comment. |
||
return; | ||
|
||
// Successful accept. Call the onconnection callback in JavaScript land. | ||
argv[1] = client_obj; | ||
} | ||
wrap_data->MakeCallback(env->onconnection_string(), arraysize(argv), argv); | ||
} | ||
|
||
template ConnectionWrap<PipeWrap, uv_pipe_t>::ConnectionWrap( | ||
Environment* env, | ||
Local<Object> object, | ||
ProviderType provider, | ||
AsyncWrap* parent); | ||
|
||
template ConnectionWrap<TCPWrap, uv_tcp_t>::ConnectionWrap( | ||
Environment* env, | ||
Local<Object> object, | ||
ProviderType provider, | ||
AsyncWrap* parent); | ||
|
||
template void ConnectionWrap<PipeWrap, uv_pipe_t>::OnConnection( | ||
uv_stream_t* handle, int status); | ||
|
||
template void ConnectionWrap<TCPWrap, uv_tcp_t>::OnConnection( | ||
uv_stream_t* handle, int status); | ||
|
||
|
||
} // namespace node |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#ifndef SRC_CONNECTION_WRAP_H_ | ||
#define SRC_CONNECTION_WRAP_H_ | ||
|
||
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
|
||
#include "env.h" | ||
#include "stream_wrap.h" | ||
#include "v8.h" | ||
|
||
namespace node { | ||
|
||
template <typename WrapType, typename UVType> | ||
class ConnectionWrap : public StreamWrap { | ||
public: | ||
UVType* UVHandle() { | ||
return &handle_; | ||
} | ||
|
||
static void OnConnection(uv_stream_t* handle, int status); | ||
|
||
protected: | ||
ConnectionWrap(Environment* env, | ||
v8::Local<v8::Object> object, | ||
ProviderType provider, | ||
AsyncWrap* parent); | ||
~ConnectionWrap() = default; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add an empty There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Absolutely, I'll add one. |
||
UVType handle_; | ||
}; | ||
|
||
|
||
} // namespace node | ||
|
||
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
|
||
#endif // SRC_CONNECTION_WRAP_H_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bnoordhuis does this make sense and have I understood the issue correctly?