Skip to content

Commit

Permalink
Modify the signatures of grpc_tcp_client_create_from_fd() and
Browse files Browse the repository at this point in the history
grpc_tcp_client_create_from_prepared_fd(), and create grpc_fd after
connect(). Otherwise if we call connect() after epoll_wait() starts,
connect() will trigger a spurious EPOLLOUT|EPOLLHUP event.
  • Loading branch information
guantaol committed Jan 17, 2020
1 parent ae64627 commit 53e42e6
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 23 deletions.
34 changes: 17 additions & 17 deletions src/core/lib/iomgr/tcp_client_posix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -247,21 +247,18 @@ static void on_writable(void* acp, grpc_error* error) {
grpc_error* grpc_tcp_client_prepare_fd(const grpc_channel_args* channel_args,
const grpc_resolved_address* addr,
grpc_resolved_address* mapped_addr,
grpc_fd** fdobj) {
int* fd) {
grpc_dualstack_mode dsmode;
int fd;
grpc_error* error;
char* name;
char* addr_str;
*fdobj = nullptr;
*fd = -1;
/* Use dualstack sockets where available. Set mapped to v6 or v4 mapped to
v6. */
if (!grpc_sockaddr_to_v4mapped(addr, mapped_addr)) {
/* addr is v4 mapped to v6 or v6. */
memcpy(mapped_addr, addr, sizeof(*mapped_addr));
}
error =
grpc_create_dualstack_socket(mapped_addr, SOCK_STREAM, 0, &dsmode, &fd);
grpc_create_dualstack_socket(mapped_addr, SOCK_STREAM, 0, &dsmode, fd);
if (error != GRPC_ERROR_NONE) {
return error;
}
Expand All @@ -271,29 +268,32 @@ grpc_error* grpc_tcp_client_prepare_fd(const grpc_channel_args* channel_args,
memcpy(mapped_addr, addr, sizeof(*mapped_addr));
}
}
if ((error = prepare_socket(mapped_addr, fd, channel_args)) !=
if ((error = prepare_socket(mapped_addr, *fd, channel_args)) !=
GRPC_ERROR_NONE) {
return error;
}
addr_str = grpc_sockaddr_to_uri(mapped_addr);
gpr_asprintf(&name, "tcp-client:%s", addr_str);
*fdobj = grpc_fd_create(fd, name, true);
gpr_free(name);
gpr_free(addr_str);
return GRPC_ERROR_NONE;
}

void grpc_tcp_client_create_from_prepared_fd(
grpc_pollset_set* interested_parties, grpc_closure* closure, grpc_fd* fdobj,
grpc_pollset_set* interested_parties, grpc_closure* closure, const int fd,
const grpc_channel_args* channel_args, const grpc_resolved_address* addr,
grpc_millis deadline, grpc_endpoint** ep) {
const int fd = grpc_fd_wrapped_fd(fdobj);
int err;
async_connect* ac;
do {
err = connect(fd, reinterpret_cast<const grpc_sockaddr*>(addr->addr),
addr->len);
} while (err < 0 && errno == EINTR);

char* name;
char* addr_str;
addr_str = grpc_sockaddr_to_uri(addr);
gpr_asprintf(&name, "tcp-client:%s", addr_str);
grpc_fd* fdobj = grpc_fd_create(fd, name, true);
gpr_free(name);
gpr_free(addr_str);

if (err >= 0) {
char* addr_str = grpc_sockaddr_to_uri(addr);
*ep = grpc_tcp_client_create_from_fd(fdobj, channel_args, addr_str);
Expand Down Expand Up @@ -340,15 +340,15 @@ static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep,
const grpc_resolved_address* addr,
grpc_millis deadline) {
grpc_resolved_address mapped_addr;
grpc_fd* fdobj = nullptr;
int fd = -1;
grpc_error* error;
*ep = nullptr;
if ((error = grpc_tcp_client_prepare_fd(channel_args, addr, &mapped_addr,
&fdobj)) != GRPC_ERROR_NONE) {
&fd)) != GRPC_ERROR_NONE) {
grpc_core::ExecCtx::Run(DEBUG_LOCATION, closure, error);
return;
}
grpc_tcp_client_create_from_prepared_fd(interested_parties, closure, fdobj,
grpc_tcp_client_create_from_prepared_fd(interested_parties, closure, fd,
channel_args, &mapped_addr, deadline,
ep);
}
Expand Down
12 changes: 6 additions & 6 deletions src/core/lib/iomgr/tcp_client_posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,33 +35,33 @@
grpc_endpoint* grpc_tcp_client_create_from_fd(
grpc_fd* fd, const grpc_channel_args* channel_args, const char* addr_str);

/* Return a configured, unbound, unconnected TCP client grpc_fd.
/* Return a configured, unbound, unconnected TCP client fd.
channel_args: may contain custom settings for the fd
addr: the destination address
mapped_addr: out parameter. addr mapped to an address appropriate to the
type of socket FD created. For example, if addr is IPv4 and dual stack
sockets are available, mapped_addr will be an IPv4-mapped IPv6 address
fdobj: out parameter. The new FD
fd: out parameter. The new FD
Returns: error, if any. Out parameters are not set on error
*/
grpc_error* grpc_tcp_client_prepare_fd(const grpc_channel_args* channel_args,
const grpc_resolved_address* addr,
grpc_resolved_address* mapped_addr,
grpc_fd** fdobj);
int* fd);

/* Connect a configured TCP client grpc_fd.
/* Connect a configured TCP client fd.
interested_parties: a set of pollsets that would be interested in this
connection being established (in order to continue their work
closure: called when complete. On success, *ep will be set.
fdobj: an FD returned from grpc_tcp_client_prepare_fd(). Ownership is taken
fd: an FD returned from grpc_tcp_client_prepare_fd().
channel_args: may contain custom settings for the endpoint
deadline: connection deadline
ep: out parameter. Set before closure is called if successful
*/
void grpc_tcp_client_create_from_prepared_fd(
grpc_pollset_set* interested_parties, grpc_closure* closure, grpc_fd* fdobj,
grpc_pollset_set* interested_parties, grpc_closure* closure, const int fd,
const grpc_channel_args* channel_args, const grpc_resolved_address* addr,
grpc_millis deadline, grpc_endpoint** ep);

Expand Down

0 comments on commit 53e42e6

Please sign in to comment.