#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/iomgr_custom.h"
grpc_closure* shutdown_complete;
bool shutdown;
+ bool so_reuseport;
grpc_resource_quota* resource_quota;
};
const grpc_channel_args* args,
grpc_tcp_server** server) {
grpc_tcp_server* s = (grpc_tcp_server*)gpr_malloc(sizeof(grpc_tcp_server));
+ // Let the implementation decide if so_reuseport can be enabled or not.
+ s->so_reuseport = true;
s->resource_quota = grpc_resource_quota_create(nullptr);
for (size_t i = 0; i < (args == nullptr ? 0 : args->num_args); i++) {
+ if (!grpc_channel_args_find_bool(args, GRPC_ARG_ALLOW_REUSEPORT, true)) {
+ s->so_reuseport = false;
+ }
if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
if (args->args[i].type == GRPC_ARG_POINTER) {
grpc_resource_quota_unref_internal(s->resource_quota);
grpc_error* error;
grpc_resolved_address sockname_temp;
- // The last argument to uv_tcp_bind is flags
+ // NOTE(lidiz) The last argument is "flags" which is unused by other
+ // implementations. Python IO managers uses it to specify SO_REUSEPORT.
+ int flags = 0;
+ if (s->so_reuseport) {
+ flags |= GRPC_CUSTOM_SOCKET_OPT_SO_REUSEPORT;
+ }
+
error = grpc_custom_socket_vtable->bind(socket, (grpc_sockaddr*)addr->addr,
- addr->len, 0);
+ addr->len, flags);
if (error != GRPC_ERROR_NONE) {
return error;
}