aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/iomgr
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lib/iomgr')
-rw-r--r--src/core/lib/iomgr/block_annotate.h8
-rw-r--r--src/core/lib/iomgr/call_combiner.h8
-rw-r--r--src/core/lib/iomgr/combiner.h8
-rw-r--r--src/core/lib/iomgr/endpoint.h8
-rw-r--r--src/core/lib/iomgr/endpoint_pair.h8
-rw-r--r--src/core/lib/iomgr/error.h8
-rw-r--r--src/core/lib/iomgr/error_internal.h8
-rw-r--r--src/core/lib/iomgr/ev_epoll1_linux.h8
-rw-r--r--src/core/lib/iomgr/ev_epollex_linux.h8
-rw-r--r--src/core/lib/iomgr/ev_epollsig_linux.h8
-rw-r--r--src/core/lib/iomgr/ev_poll_posix.h8
-rw-r--r--src/core/lib/iomgr/ev_posix.cc3
-rw-r--r--src/core/lib/iomgr/ev_posix.h8
-rw-r--r--src/core/lib/iomgr/exec_ctx.h8
-rw-r--r--src/core/lib/iomgr/executor.h8
-rw-r--r--src/core/lib/iomgr/fork_posix.cc90
-rw-r--r--src/core/lib/iomgr/fork_windows.cc39
-rw-r--r--src/core/lib/iomgr/gethostname.h8
-rw-r--r--src/core/lib/iomgr/iocp_windows.h8
-rw-r--r--src/core/lib/iomgr/iomgr.h8
-rw-r--r--src/core/lib/iomgr/iomgr_internal.h8
-rw-r--r--src/core/lib/iomgr/iomgr_uv.h8
-rw-r--r--src/core/lib/iomgr/load_file.h8
-rw-r--r--src/core/lib/iomgr/polling_entity.h7
-rw-r--r--src/core/lib/iomgr/pollset.h8
-rw-r--r--src/core/lib/iomgr/pollset_set.h8
-rw-r--r--src/core/lib/iomgr/pollset_uv.h8
-rw-r--r--src/core/lib/iomgr/pollset_windows.h8
-rw-r--r--src/core/lib/iomgr/port.h4
-rw-r--r--src/core/lib/iomgr/resolve_address.h8
-rw-r--r--src/core/lib/iomgr/resource_quota.h8
-rw-r--r--src/core/lib/iomgr/sockaddr_utils.cc2
-rw-r--r--src/core/lib/iomgr/sockaddr_utils.h8
-rw-r--r--src/core/lib/iomgr/socket_factory_posix.h8
-rw-r--r--src/core/lib/iomgr/socket_mutator.h8
-rw-r--r--src/core/lib/iomgr/socket_utils.h8
-rw-r--r--src/core/lib/iomgr/socket_utils_posix.h8
-rw-r--r--src/core/lib/iomgr/socket_windows.h8
-rw-r--r--src/core/lib/iomgr/tcp_client.h8
-rw-r--r--src/core/lib/iomgr/tcp_client_posix.cc2
-rw-r--r--src/core/lib/iomgr/tcp_client_posix.h8
-rw-r--r--src/core/lib/iomgr/tcp_client_uv.cc2
-rw-r--r--src/core/lib/iomgr/tcp_client_windows.cc2
-rw-r--r--src/core/lib/iomgr/tcp_posix.h8
-rw-r--r--src/core/lib/iomgr/tcp_server.h8
-rw-r--r--src/core/lib/iomgr/tcp_server_utils_posix.h8
-rw-r--r--src/core/lib/iomgr/tcp_server_utils_posix_common.cc2
-rw-r--r--src/core/lib/iomgr/tcp_uv.h8
-rw-r--r--src/core/lib/iomgr/tcp_windows.h8
-rw-r--r--src/core/lib/iomgr/time_averaged_stats.h8
-rw-r--r--src/core/lib/iomgr/timer.h8
-rw-r--r--src/core/lib/iomgr/timer_heap.h8
-rw-r--r--src/core/lib/iomgr/timer_manager.h8
-rw-r--r--src/core/lib/iomgr/udp_server.cc110
-rw-r--r--src/core/lib/iomgr/udp_server.h19
-rw-r--r--src/core/lib/iomgr/unix_sockets_posix.h8
-rw-r--r--src/core/lib/iomgr/wakeup_fd_cv.h8
-rw-r--r--src/core/lib/iomgr/wakeup_fd_pipe.h8
-rw-r--r--src/core/lib/iomgr/wakeup_fd_posix.h8
59 files changed, 238 insertions, 420 deletions
diff --git a/src/core/lib/iomgr/block_annotate.h b/src/core/lib/iomgr/block_annotate.h
index fcbfe9eb1a..340ebcb1af 100644
--- a/src/core/lib/iomgr/block_annotate.h
+++ b/src/core/lib/iomgr/block_annotate.h
@@ -19,17 +19,9 @@
#ifndef GRPC_CORE_LIB_IOMGR_BLOCK_ANNOTATE_H
#define GRPC_CORE_LIB_IOMGR_BLOCK_ANNOTATE_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
void gpr_thd_start_blocking_region();
void gpr_thd_end_blocking_region();
-#ifdef __cplusplus
-}
-#endif
-
/* These annotations identify the beginning and end of regions where
the code may block for reasons other than synchronization functions.
These include poll, epoll, and getaddrinfo. */
diff --git a/src/core/lib/iomgr/call_combiner.h b/src/core/lib/iomgr/call_combiner.h
index 77420fa3e0..c07af51c91 100644
--- a/src/core/lib/iomgr/call_combiner.h
+++ b/src/core/lib/iomgr/call_combiner.h
@@ -27,10 +27,6 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/support/mpscq.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
// A simple, lock-free mechanism for serializing activity related to a
// single call. This is similar to a combiner but is more lightweight.
//
@@ -122,8 +118,4 @@ void grpc_call_combiner_cancel(grpc_exec_ctx* exec_ctx,
grpc_call_combiner* call_combiner,
grpc_error* error);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_CALL_COMBINER_H */
diff --git a/src/core/lib/iomgr/combiner.h b/src/core/lib/iomgr/combiner.h
index e99b06306f..0c05511331 100644
--- a/src/core/lib/iomgr/combiner.h
+++ b/src/core/lib/iomgr/combiner.h
@@ -26,10 +26,6 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/support/mpscq.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
// Provides serialized access to some resource.
// Each action queued on a combiner is executed serially in a borrowed thread.
// The actual thread executing actions may change over time (but there will only
@@ -67,8 +63,4 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx* exec_ctx);
extern grpc_core::TraceFlag grpc_combiner_trace;
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_COMBINER_H */
diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h
index 1b0a9e725e..6ab0a6591c 100644
--- a/src/core/lib/iomgr/endpoint.h
+++ b/src/core/lib/iomgr/endpoint.h
@@ -26,10 +26,6 @@
#include "src/core/lib/iomgr/pollset_set.h"
#include "src/core/lib/iomgr/resource_quota.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* An endpoint caps a streaming channel between two communicating processes.
Examples may be: a tcp socket, <stdin+stdout>, or some shared memory. */
@@ -106,8 +102,4 @@ struct grpc_endpoint {
const grpc_endpoint_vtable* vtable;
};
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_ENDPOINT_H */
diff --git a/src/core/lib/iomgr/endpoint_pair.h b/src/core/lib/iomgr/endpoint_pair.h
index 219eea8550..506ffc88b4 100644
--- a/src/core/lib/iomgr/endpoint_pair.h
+++ b/src/core/lib/iomgr/endpoint_pair.h
@@ -21,10 +21,6 @@
#include "src/core/lib/iomgr/endpoint.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct {
grpc_endpoint* client;
grpc_endpoint* server;
@@ -33,8 +29,4 @@ typedef struct {
grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char* name,
grpc_channel_args* args);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_ENDPOINT_PAIR_H */
diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h
index d10bf0b359..4759ee0791 100644
--- a/src/core/lib/iomgr/error.h
+++ b/src/core/lib/iomgr/error.h
@@ -29,10 +29,6 @@
#include "src/core/lib/debug/trace.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/// Opaque representation of an error.
/// See https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md for a
/// full write up of this object.
@@ -203,8 +199,4 @@ bool grpc_log_if_error(const char* what, grpc_error* error, const char* file,
#define GRPC_LOG_IF_ERROR(what, error) \
grpc_log_if_error((what), (error), __FILE__, __LINE__)
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_ERROR_H */
diff --git a/src/core/lib/iomgr/error_internal.h b/src/core/lib/iomgr/error_internal.h
index d5ccbae9e7..6cb09c2cdb 100644
--- a/src/core/lib/iomgr/error_internal.h
+++ b/src/core/lib/iomgr/error_internal.h
@@ -25,10 +25,6 @@
#include <grpc/support/sync.h>
#include "src/core/lib/iomgr/error.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct grpc_linked_error grpc_linked_error;
struct grpc_linked_error {
@@ -62,8 +58,4 @@ struct grpc_error {
bool grpc_error_is_special(struct grpc_error* err);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_ERROR_INTERNAL_H */
diff --git a/src/core/lib/iomgr/ev_epoll1_linux.h b/src/core/lib/iomgr/ev_epoll1_linux.h
index 3e66747f6c..9a1b96bd45 100644
--- a/src/core/lib/iomgr/ev_epoll1_linux.h
+++ b/src/core/lib/iomgr/ev_epoll1_linux.h
@@ -22,16 +22,8 @@
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/port.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
// a polling engine that utilizes a singleton epoll set and turnstile polling
const grpc_event_engine_vtable* grpc_init_epoll1_linux(bool explicit_request);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_EV_EPOLL1_LINUX_H */
diff --git a/src/core/lib/iomgr/ev_epollex_linux.h b/src/core/lib/iomgr/ev_epollex_linux.h
index 22b536c7d4..ffa7fc7f32 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.h
+++ b/src/core/lib/iomgr/ev_epollex_linux.h
@@ -22,15 +22,7 @@
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/port.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
const grpc_event_engine_vtable* grpc_init_epollex_linux(
bool explicitly_requested);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_EV_EPOLLEX_LINUX_H */
diff --git a/src/core/lib/iomgr/ev_epollsig_linux.h b/src/core/lib/iomgr/ev_epollsig_linux.h
index ca68595734..5b8aba9d9f 100644
--- a/src/core/lib/iomgr/ev_epollsig_linux.h
+++ b/src/core/lib/iomgr/ev_epollsig_linux.h
@@ -22,10 +22,6 @@
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/port.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
const grpc_event_engine_vtable* grpc_init_epollsig_linux(bool explicit_request);
#ifdef GRPC_LINUX_EPOLL
@@ -34,8 +30,4 @@ void* grpc_pollset_get_polling_island(grpc_pollset* ps);
bool grpc_are_polling_islands_equal(void* p, void* q);
#endif /* defined(GRPC_LINUX_EPOLL) */
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_EV_EPOLLSIG_LINUX_H */
diff --git a/src/core/lib/iomgr/ev_poll_posix.h b/src/core/lib/iomgr/ev_poll_posix.h
index 626e95bc8f..f6bc624d4f 100644
--- a/src/core/lib/iomgr/ev_poll_posix.h
+++ b/src/core/lib/iomgr/ev_poll_posix.h
@@ -21,15 +21,7 @@
#include "src/core/lib/iomgr/ev_posix.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
const grpc_event_engine_vtable* grpc_init_poll_posix(bool explicit_request);
const grpc_event_engine_vtable* grpc_init_poll_cv_posix(bool explicit_request);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_EV_POLL_POSIX_H */
diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc
index 80dde6d857..031c97564a 100644
--- a/src/core/lib/iomgr/ev_posix.cc
+++ b/src/core/lib/iomgr/ev_posix.cc
@@ -59,8 +59,6 @@ typedef struct {
namespace {
-extern "C" {
-
grpc_poll_function_type real_poll_function;
int dummy_poll(struct pollfd fds[], nfds_t nfds, int timeout) {
@@ -72,7 +70,6 @@ int dummy_poll(struct pollfd fds[], nfds_t nfds, int timeout) {
return -1;
}
}
-} // extern "C"
const grpc_event_engine_vtable* init_non_polling(bool explicit_request) {
if (!explicit_request) {
diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h
index 8f45d2e3a9..16fa10ca56 100644
--- a/src/core/lib/iomgr/ev_posix.h
+++ b/src/core/lib/iomgr/ev_posix.h
@@ -27,10 +27,6 @@
#include "src/core/lib/iomgr/pollset_set.h"
#include "src/core/lib/iomgr/wakeup_fd_posix.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
extern grpc_core::TraceFlag grpc_polling_trace; /* Disabled by default */
typedef struct grpc_fd grpc_fd;
@@ -162,8 +158,4 @@ extern grpc_poll_function_type grpc_poll_function;
void grpc_set_event_engine_test_only(const grpc_event_engine_vtable*);
const grpc_event_engine_vtable* grpc_get_event_engine_test_only();
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_EV_POSIX_H */
diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h
index bd27506152..b415d2c255 100644
--- a/src/core/lib/iomgr/exec_ctx.h
+++ b/src/core/lib/iomgr/exec_ctx.h
@@ -24,10 +24,6 @@
#include "src/core/lib/iomgr/closure.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef gpr_atm grpc_millis;
#define GRPC_MILLIS_INF_FUTURE GPR_ATM_MAX
@@ -124,8 +120,4 @@ gpr_timespec grpc_millis_to_timespec(grpc_millis millis, gpr_clock_type clock);
grpc_millis grpc_timespec_to_millis_round_down(gpr_timespec timespec);
grpc_millis grpc_timespec_to_millis_round_up(gpr_timespec timespec);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_EXEC_CTX_H */
diff --git a/src/core/lib/iomgr/executor.h b/src/core/lib/iomgr/executor.h
index 8418ace06e..d349083eeb 100644
--- a/src/core/lib/iomgr/executor.h
+++ b/src/core/lib/iomgr/executor.h
@@ -21,10 +21,6 @@
#include "src/core/lib/iomgr/closure.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef enum {
GRPC_EXECUTOR_SHORT,
GRPC_EXECUTOR_LONG
@@ -49,8 +45,4 @@ bool grpc_executor_is_threaded();
grpc_executor_shutdown */
void grpc_executor_set_threading(grpc_exec_ctx* exec_ctx, bool enable);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */
diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc
new file mode 100644
index 0000000000..f3cfd141b6
--- /dev/null
+++ b/src/core/lib/iomgr/fork_posix.cc
@@ -0,0 +1,90 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "src/core/lib/iomgr/port.h"
+
+#ifdef GRPC_POSIX_FORK
+
+#include <string.h>
+
+#include <grpc/fork.h>
+#include <grpc/support/log.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/useful.h>
+
+#include "src/core/lib/iomgr/ev_posix.h"
+#include "src/core/lib/iomgr/executor.h"
+#include "src/core/lib/iomgr/timer_manager.h"
+#include "src/core/lib/iomgr/wakeup_fd_posix.h"
+#include "src/core/lib/support/env.h"
+#include "src/core/lib/support/fork.h"
+#include "src/core/lib/support/thd_internal.h"
+#include "src/core/lib/surface/init.h"
+
+/*
+ * NOTE: FORKING IS NOT GENERALLY SUPPORTED, THIS IS ONLY INTENDED TO WORK
+ * AROUND VERY SPECIFIC USE CASES.
+ */
+
+void grpc_prefork() {
+ if (!grpc_fork_support_enabled()) {
+ gpr_log(GPR_ERROR,
+ "Fork support not enabled; try running with the "
+ "environment variable GRPC_ENABLE_FORK_SUPPORT=1");
+ return;
+ }
+ if (grpc_is_initialized()) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_timer_manager_set_threading(false);
+ grpc_executor_set_threading(&exec_ctx, false);
+ grpc_exec_ctx_finish(&exec_ctx);
+ if (!gpr_await_threads(
+ gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_seconds(3, GPR_TIMESPAN)))) {
+ gpr_log(GPR_ERROR, "gRPC thread still active! Cannot fork!");
+ }
+ }
+}
+
+void grpc_postfork_parent() {
+ if (grpc_is_initialized()) {
+ grpc_timer_manager_set_threading(true);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_executor_set_threading(&exec_ctx, true);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+}
+
+void grpc_postfork_child() {
+ if (grpc_is_initialized()) {
+ grpc_timer_manager_set_threading(true);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_executor_set_threading(&exec_ctx, true);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+}
+
+void grpc_fork_handlers_auto_register() {
+ if (grpc_fork_support_enabled()) {
+#ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK
+ pthread_atfork(grpc_prefork, grpc_postfork_parent, grpc_postfork_child);
+#endif // GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK
+ }
+}
+
+#endif // GRPC_POSIX_FORK
diff --git a/src/core/lib/iomgr/fork_windows.cc b/src/core/lib/iomgr/fork_windows.cc
new file mode 100644
index 0000000000..f9986f33c7
--- /dev/null
+++ b/src/core/lib/iomgr/fork_windows.cc
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "src/core/lib/iomgr/port.h"
+
+#ifndef GRPC_POSIX_FORK
+
+#include <grpc/fork.h>
+#include <grpc/support/log.h>
+
+/*
+ * NOTE: FORKING IS NOT GENERALLY SUPPORTED, THIS IS ONLY INTENDED TO WORK
+ * AROUND VERY SPECIFIC USE CASES.
+ */
+
+void grpc_prefork() { gpr_log(GPR_ERROR, "Forking not supported on Windows"); }
+
+void grpc_postfork_parent() {}
+
+void grpc_postfork_child() {}
+
+void grpc_fork_handlers_auto_register() {}
+
+#endif // GRPC_POSIX_FORK
diff --git a/src/core/lib/iomgr/gethostname.h b/src/core/lib/iomgr/gethostname.h
index 2e65b5ffbf..9f10b4afa7 100644
--- a/src/core/lib/iomgr/gethostname.h
+++ b/src/core/lib/iomgr/gethostname.h
@@ -19,16 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_GETHOSTNAME_H
#define GRPC_CORE_LIB_IOMGR_GETHOSTNAME_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
// Returns the hostname of the local machine.
// Caller takes ownership of result.
char* grpc_gethostname();
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_GETHOSTNAME_H */
diff --git a/src/core/lib/iomgr/iocp_windows.h b/src/core/lib/iomgr/iocp_windows.h
index d112c50538..0e9c3481f7 100644
--- a/src/core/lib/iomgr/iocp_windows.h
+++ b/src/core/lib/iomgr/iocp_windows.h
@@ -27,10 +27,6 @@
#include "src/core/lib/iomgr/socket_windows.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef enum {
GRPC_IOCP_WORK_WORK,
GRPC_IOCP_WORK_TIMEOUT,
@@ -45,10 +41,6 @@ void grpc_iocp_flush(void);
void grpc_iocp_shutdown(void);
void grpc_iocp_add_socket(grpc_winsocket*);
-#ifdef __cplusplus
-}
-#endif
-
#endif
#endif /* GRPC_CORE_LIB_IOMGR_IOCP_WINDOWS_H */
diff --git a/src/core/lib/iomgr/iomgr.h b/src/core/lib/iomgr/iomgr.h
index d1549c8c63..2f00c0343d 100644
--- a/src/core/lib/iomgr/iomgr.h
+++ b/src/core/lib/iomgr/iomgr.h
@@ -22,10 +22,6 @@
#include <grpc/impl/codegen/exec_ctx_fwd.h>
#include "src/core/lib/iomgr/port.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/** Initializes the iomgr. */
void grpc_iomgr_init(grpc_exec_ctx* exec_ctx);
@@ -36,8 +32,4 @@ void grpc_iomgr_start(grpc_exec_ctx* exec_ctx);
* exec_ctx. */
void grpc_iomgr_shutdown(grpc_exec_ctx* exec_ctx);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_IOMGR_H */
diff --git a/src/core/lib/iomgr/iomgr_internal.h b/src/core/lib/iomgr/iomgr_internal.h
index b818c68da0..20b3cb70d0 100644
--- a/src/core/lib/iomgr/iomgr_internal.h
+++ b/src/core/lib/iomgr/iomgr_internal.h
@@ -23,10 +23,6 @@
#include "src/core/lib/iomgr/iomgr.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct grpc_iomgr_object {
char* name;
struct grpc_iomgr_object* next;
@@ -44,8 +40,4 @@ void grpc_iomgr_platform_shutdown(void);
bool grpc_iomgr_abort_on_leaks(void);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_IOMGR_INTERNAL_H */
diff --git a/src/core/lib/iomgr/iomgr_uv.h b/src/core/lib/iomgr/iomgr_uv.h
index bc42ca8c1c..3b4daaa73b 100644
--- a/src/core/lib/iomgr/iomgr_uv.h
+++ b/src/core/lib/iomgr/iomgr_uv.h
@@ -23,18 +23,10 @@
#include <grpc/support/thd.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* The thread ID of the thread on which grpc was initialized. Used to verify
* that all calls into libuv are made on that same thread */
extern gpr_thd_id g_init_thread;
-#ifdef __cplusplus
-}
-#endif
-
#ifdef GRPC_UV_THREAD_CHECK
#define GRPC_UV_ASSERT_SAME_THREAD() \
GPR_ASSERT(gpr_thd_currentid() == g_init_thread)
diff --git a/src/core/lib/iomgr/load_file.h b/src/core/lib/iomgr/load_file.h
index 5b367c189d..a7336527ce 100644
--- a/src/core/lib/iomgr/load_file.h
+++ b/src/core/lib/iomgr/load_file.h
@@ -25,17 +25,9 @@
#include "src/core/lib/iomgr/error.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Loads the content of a file into a slice. add_null_terminator will add
a NULL terminator if non-zero. */
grpc_error* grpc_load_file(const char* filename, int add_null_terminator,
grpc_slice* slice);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_LOAD_FILE_H */
diff --git a/src/core/lib/iomgr/polling_entity.h b/src/core/lib/iomgr/polling_entity.h
index 867e085153..dbe579e60d 100644
--- a/src/core/lib/iomgr/polling_entity.h
+++ b/src/core/lib/iomgr/polling_entity.h
@@ -22,10 +22,6 @@
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/iomgr/pollset_set.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef enum grpc_pollset_tag {
GRPC_POLLS_NONE,
GRPC_POLLS_POLLSET,
@@ -68,8 +64,5 @@ void grpc_polling_entity_add_to_pollset_set(grpc_exec_ctx* exec_ctx,
void grpc_polling_entity_del_from_pollset_set(grpc_exec_ctx* exec_ctx,
grpc_polling_entity* pollent,
grpc_pollset_set* pss_dst);
-#ifdef __cplusplus
-}
-#endif
#endif /* GRPC_CORE_LIB_IOMGR_POLLING_ENTITY_H */
diff --git a/src/core/lib/iomgr/pollset.h b/src/core/lib/iomgr/pollset.h
index 6911a8ee12..d5d78f3101 100644
--- a/src/core/lib/iomgr/pollset.h
+++ b/src/core/lib/iomgr/pollset.h
@@ -25,10 +25,6 @@
#include "src/core/lib/iomgr/exec_ctx.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
extern grpc_core::DebugOnlyTraceFlag grpc_trace_fd_refcount;
/* A grpc_pollset is a set of file descriptors that a higher level item is
@@ -82,8 +78,4 @@ grpc_error* grpc_pollset_kick(grpc_exec_ctx* exec_ctx, grpc_pollset* pollset,
grpc_pollset_worker* specific_worker)
GRPC_MUST_USE_RESULT;
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_POLLSET_H */
diff --git a/src/core/lib/iomgr/pollset_set.h b/src/core/lib/iomgr/pollset_set.h
index 0167a50a56..089c15cc94 100644
--- a/src/core/lib/iomgr/pollset_set.h
+++ b/src/core/lib/iomgr/pollset_set.h
@@ -21,10 +21,6 @@
#include "src/core/lib/iomgr/pollset.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* A grpc_pollset_set is a set of pollsets that are interested in an
action. Adding a pollset to a pollset_set automatically adds any
fd's (etc) that have been registered with the set_set to that pollset.
@@ -48,8 +44,4 @@ void grpc_pollset_set_del_pollset_set(grpc_exec_ctx* exec_ctx,
grpc_pollset_set* bag,
grpc_pollset_set* item);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_POLLSET_SET_H */
diff --git a/src/core/lib/iomgr/pollset_uv.h b/src/core/lib/iomgr/pollset_uv.h
index 5cc9faf4ff..566c110ca6 100644
--- a/src/core/lib/iomgr/pollset_uv.h
+++ b/src/core/lib/iomgr/pollset_uv.h
@@ -19,17 +19,9 @@
#ifndef GRPC_CORE_LIB_IOMGR_POLLSET_UV_H
#define GRPC_CORE_LIB_IOMGR_POLLSET_UV_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
extern int grpc_pollset_work_run_loop;
void grpc_pollset_global_init(void);
void grpc_pollset_global_shutdown(void);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_POLLSET_UV_H */
diff --git a/src/core/lib/iomgr/pollset_windows.h b/src/core/lib/iomgr/pollset_windows.h
index f6da9da601..93fe7d669b 100644
--- a/src/core/lib/iomgr/pollset_windows.h
+++ b/src/core/lib/iomgr/pollset_windows.h
@@ -26,10 +26,6 @@
#ifdef GRPC_WINSOCK_SOCKET
#include "src/core/lib/iomgr/socket_windows.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* There isn't really any such thing as a pollset under Windows, due to the
nature of the IO completion ports. A Windows "pollset" is merely a mutex
used to synchronize with the IOCP, and workers are condition variables
@@ -67,10 +63,6 @@ struct grpc_pollset {
void grpc_pollset_global_init(void);
void grpc_pollset_global_shutdown(void);
-#ifdef __cplusplus
-}
-#endif
-
#endif
#endif /* GRPC_CORE_LIB_IOMGR_POLLSET_WINDOWS_H */
diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h
index 1cc6d98491..9fae8c0052 100644
--- a/src/core/lib/iomgr/port.h
+++ b/src/core/lib/iomgr/port.h
@@ -30,6 +30,7 @@
#define GRPC_HAVE_IP_PKTINFO 1
#define GRPC_HAVE_MSG_NOSIGNAL 1
#define GRPC_HAVE_UNIX_SOCKET 1
+#define GRPC_POSIX_FORK 1
#define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1
#define GRPC_POSIX_SOCKET 1
#define GRPC_POSIX_SOCKETADDR 1
@@ -59,6 +60,7 @@
#define GRPC_HAVE_MSG_NOSIGNAL 1
#define GRPC_HAVE_UNIX_SOCKET 1
#define GRPC_LINUX_MULTIPOLL_WITH_EPOLL 1
+#define GRPC_POSIX_FORK 1
#define GRPC_POSIX_HOST_NAME_MAX 1
#define GRPC_POSIX_SOCKET 1
#define GRPC_POSIX_SOCKETADDR 1
@@ -90,6 +92,7 @@
#define GRPC_HAVE_SO_NOSIGPIPE 1
#define GRPC_HAVE_UNIX_SOCKET 1
#define GRPC_MSG_IOVLEN_TYPE int
+#define GRPC_POSIX_FORK 1
#define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1
#define GRPC_POSIX_SOCKET 1
#define GRPC_POSIX_SOCKETADDR 1
@@ -103,6 +106,7 @@
#define GRPC_HAVE_IPV6_RECVPKTINFO 1
#define GRPC_HAVE_SO_NOSIGPIPE 1
#define GRPC_HAVE_UNIX_SOCKET 1
+#define GRPC_POSIX_FORK 1
#define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1
#define GRPC_POSIX_SOCKET 1
#define GRPC_POSIX_SOCKETADDR 1
diff --git a/src/core/lib/iomgr/resolve_address.h b/src/core/lib/iomgr/resolve_address.h
index 847e10f177..5105020404 100644
--- a/src/core/lib/iomgr/resolve_address.h
+++ b/src/core/lib/iomgr/resolve_address.h
@@ -25,10 +25,6 @@
#define GRPC_MAX_SOCKADDR_SIZE 128
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct {
char addr[GRPC_MAX_SOCKADDR_SIZE];
size_t len;
@@ -56,8 +52,4 @@ extern grpc_error* (*grpc_blocking_resolve_address)(
const char* name, const char* default_port,
grpc_resolved_addresses** addresses);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_RESOLVE_ADDRESS_H */
diff --git a/src/core/lib/iomgr/resource_quota.h b/src/core/lib/iomgr/resource_quota.h
index 3af93a883e..787370307a 100644
--- a/src/core/lib/iomgr/resource_quota.h
+++ b/src/core/lib/iomgr/resource_quota.h
@@ -24,10 +24,6 @@
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/exec_ctx.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/** \file Tracks resource usage against a pool.
The current implementation tracks only memory usage, but in the future
@@ -154,8 +150,4 @@ grpc_slice grpc_resource_user_slice_malloc(grpc_exec_ctx* exec_ctx,
grpc_resource_user* resource_user,
size_t size);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H */
diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc
index 3477fb52cd..0c0a2fe5b2 100644
--- a/src/core/lib/iomgr/sockaddr_utils.cc
+++ b/src/core/lib/iomgr/sockaddr_utils.cc
@@ -148,7 +148,7 @@ int grpc_sockaddr_to_string(char** out,
grpc_resolved_address addr_normalized;
char ntop_buf[INET6_ADDRSTRLEN];
const void* ip = nullptr;
- int port;
+ int port = 0;
uint32_t sin6_scope_id = 0;
int ret;
diff --git a/src/core/lib/iomgr/sockaddr_utils.h b/src/core/lib/iomgr/sockaddr_utils.h
index 090470d49e..e3bd51a4ad 100644
--- a/src/core/lib/iomgr/sockaddr_utils.h
+++ b/src/core/lib/iomgr/sockaddr_utils.h
@@ -21,10 +21,6 @@
#include "src/core/lib/iomgr/resolve_address.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Returns true if addr is an IPv4-mapped IPv6 address within the
::ffff:0.0.0.0/96 range, or false otherwise.
@@ -81,8 +77,4 @@ const char* grpc_sockaddr_get_uri_scheme(const grpc_resolved_address* addr);
int grpc_sockaddr_get_family(const grpc_resolved_address* resolved_addr);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_UTILS_H */
diff --git a/src/core/lib/iomgr/socket_factory_posix.h b/src/core/lib/iomgr/socket_factory_posix.h
index e8257b07c4..af57cc5b60 100644
--- a/src/core/lib/iomgr/socket_factory_posix.h
+++ b/src/core/lib/iomgr/socket_factory_posix.h
@@ -23,10 +23,6 @@
#include <grpc/support/sync.h>
#include "src/core/lib/iomgr/resolve_address.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/** The virtual table of grpc_socket_factory */
typedef struct {
/** Replacement for socket(2) */
@@ -68,8 +64,4 @@ int grpc_socket_factory_compare(grpc_socket_factory* a, grpc_socket_factory* b);
grpc_socket_factory* grpc_socket_factory_ref(grpc_socket_factory* factory);
void grpc_socket_factory_unref(grpc_socket_factory* factory);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_SOCKET_FACTORY_POSIX_H */
diff --git a/src/core/lib/iomgr/socket_mutator.h b/src/core/lib/iomgr/socket_mutator.h
index b4103f7e93..0a97cf657f 100644
--- a/src/core/lib/iomgr/socket_mutator.h
+++ b/src/core/lib/iomgr/socket_mutator.h
@@ -24,10 +24,6 @@
#include <stdbool.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/** The virtual table of grpc_socket_mutator */
typedef struct {
/** Mutates the socket opitons of \a fd */
@@ -60,8 +56,4 @@ int grpc_socket_mutator_compare(grpc_socket_mutator* a, grpc_socket_mutator* b);
grpc_socket_mutator* grpc_socket_mutator_ref(grpc_socket_mutator* mutator);
void grpc_socket_mutator_unref(grpc_socket_mutator* mutator);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_SOCKET_MUTATOR_H */
diff --git a/src/core/lib/iomgr/socket_utils.h b/src/core/lib/iomgr/socket_utils.h
index 4816ab6be7..9fd141b6de 100644
--- a/src/core/lib/iomgr/socket_utils.h
+++ b/src/core/lib/iomgr/socket_utils.h
@@ -21,15 +21,7 @@
#include <stddef.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* A wrapper for inet_ntop on POSIX systems and InetNtop on Windows systems */
const char* grpc_inet_ntop(int af, const void* src, char* dst, size_t size);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_H */
diff --git a/src/core/lib/iomgr/socket_utils_posix.h b/src/core/lib/iomgr/socket_utils_posix.h
index 7a9c8139e7..77df4205ff 100644
--- a/src/core/lib/iomgr/socket_utils_posix.h
+++ b/src/core/lib/iomgr/socket_utils_posix.h
@@ -29,10 +29,6 @@
#include "src/core/lib/iomgr/socket_factory_posix.h"
#include "src/core/lib/iomgr/socket_mutator.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* a wrapper for accept or accept4 */
int grpc_accept4(int sockfd, grpc_resolved_address* resolved_addr, int nonblock,
int cloexec);
@@ -133,8 +129,4 @@ grpc_error* grpc_create_dualstack_socket_using_factory(
grpc_socket_factory* factory, const grpc_resolved_address* addr, int type,
int protocol, grpc_dualstack_mode* dsmode, int* newfd);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_POSIX_H */
diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h
index c3ad99d82f..04e0a89d70 100644
--- a/src/core/lib/iomgr/socket_windows.h
+++ b/src/core/lib/iomgr/socket_windows.h
@@ -31,10 +31,6 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* This holds the data for an outstanding read or write on a socket.
The mutex to protect the concurrent access to that data is the one
inside the winsocket wrapper. */
@@ -114,10 +110,6 @@ void grpc_socket_become_ready(grpc_exec_ctx* exec_ctx,
grpc_winsocket* winsocket,
grpc_winsocket_callback_info* ci);
-#ifdef __cplusplus
-}
-#endif
-
#endif
#endif /* GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H */
diff --git a/src/core/lib/iomgr/tcp_client.h b/src/core/lib/iomgr/tcp_client.h
index c18d8a9316..75e2fe0f36 100644
--- a/src/core/lib/iomgr/tcp_client.h
+++ b/src/core/lib/iomgr/tcp_client.h
@@ -25,10 +25,6 @@
#include "src/core/lib/iomgr/pollset_set.h"
#include "src/core/lib/iomgr/resolve_address.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Asynchronously connect to an address (specified as (addr, len)), and call
cb with arg and the completed connection when done (or call cb with arg and
NULL on failure).
@@ -41,8 +37,4 @@ void grpc_tcp_client_connect(grpc_exec_ctx* exec_ctx, grpc_closure* on_connect,
const grpc_resolved_address* addr,
grpc_millis deadline);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_TCP_CLIENT_H */
diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc
index 8a6262b53d..4cb2ac49d5 100644
--- a/src/core/lib/iomgr/tcp_client_posix.cc
+++ b/src/core/lib/iomgr/tcp_client_posix.cc
@@ -334,13 +334,11 @@ done:
}
// overridden by api_fuzzer.c
-extern "C" {
void (*grpc_tcp_client_connect_impl)(
grpc_exec_ctx* exec_ctx, grpc_closure* closure, grpc_endpoint** ep,
grpc_pollset_set* interested_parties, const grpc_channel_args* channel_args,
const grpc_resolved_address* addr,
grpc_millis deadline) = tcp_client_connect_impl;
-}
void grpc_tcp_client_connect(grpc_exec_ctx* exec_ctx, grpc_closure* closure,
grpc_endpoint** ep,
diff --git a/src/core/lib/iomgr/tcp_client_posix.h b/src/core/lib/iomgr/tcp_client_posix.h
index 13d917891e..2b1fe79e90 100644
--- a/src/core/lib/iomgr/tcp_client_posix.h
+++ b/src/core/lib/iomgr/tcp_client_posix.h
@@ -23,16 +23,8 @@
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/tcp_client.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
grpc_endpoint* grpc_tcp_client_create_from_fd(
grpc_exec_ctx* exec_ctx, grpc_fd* fd, const grpc_channel_args* channel_args,
const char* addr_str);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_TCP_CLIENT_POSIX_H */
diff --git a/src/core/lib/iomgr/tcp_client_uv.cc b/src/core/lib/iomgr/tcp_client_uv.cc
index 7a5727ec53..5cca0c9936 100644
--- a/src/core/lib/iomgr/tcp_client_uv.cc
+++ b/src/core/lib/iomgr/tcp_client_uv.cc
@@ -161,13 +161,11 @@ static void tcp_client_connect_impl(grpc_exec_ctx* exec_ctx,
}
// overridden by api_fuzzer.c
-extern "C" {
void (*grpc_tcp_client_connect_impl)(
grpc_exec_ctx* exec_ctx, grpc_closure* closure, grpc_endpoint** ep,
grpc_pollset_set* interested_parties, const grpc_channel_args* channel_args,
const grpc_resolved_address* addr,
grpc_millis deadline) = tcp_client_connect_impl;
-}
void grpc_tcp_client_connect(grpc_exec_ctx* exec_ctx, grpc_closure* closure,
grpc_endpoint** ep,
diff --git a/src/core/lib/iomgr/tcp_client_windows.cc b/src/core/lib/iomgr/tcp_client_windows.cc
index 103e6b78de..5e30725e90 100644
--- a/src/core/lib/iomgr/tcp_client_windows.cc
+++ b/src/core/lib/iomgr/tcp_client_windows.cc
@@ -226,13 +226,11 @@ failure:
}
// overridden by api_fuzzer.c
-extern "C" {
void (*grpc_tcp_client_connect_impl)(
grpc_exec_ctx* exec_ctx, grpc_closure* closure, grpc_endpoint** ep,
grpc_pollset_set* interested_parties, const grpc_channel_args* channel_args,
const grpc_resolved_address* addr,
grpc_millis deadline) = tcp_client_connect_impl;
-}
void grpc_tcp_client_connect(grpc_exec_ctx* exec_ctx, grpc_closure* closure,
grpc_endpoint** ep,
diff --git a/src/core/lib/iomgr/tcp_posix.h b/src/core/lib/iomgr/tcp_posix.h
index ba851463d6..09051b7ed6 100644
--- a/src/core/lib/iomgr/tcp_posix.h
+++ b/src/core/lib/iomgr/tcp_posix.h
@@ -33,10 +33,6 @@
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/ev_posix.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
extern grpc_core::TraceFlag grpc_tcp_trace;
/* Create a tcp endpoint given a file desciptor and a read slice size.
@@ -57,8 +53,4 @@ int grpc_tcp_fd(grpc_endpoint* ep);
void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep,
int* fd, grpc_closure* done);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_TCP_POSIX_H */
diff --git a/src/core/lib/iomgr/tcp_server.h b/src/core/lib/iomgr/tcp_server.h
index ef983199b8..a1757a2b3e 100644
--- a/src/core/lib/iomgr/tcp_server.h
+++ b/src/core/lib/iomgr/tcp_server.h
@@ -25,10 +25,6 @@
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/resolve_address.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Forward decl of grpc_tcp_server */
typedef struct grpc_tcp_server grpc_tcp_server;
@@ -102,8 +98,4 @@ void grpc_tcp_server_unref(grpc_exec_ctx* exec_ctx, grpc_tcp_server* s);
void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx* exec_ctx,
grpc_tcp_server* s);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_TCP_SERVER_H */
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix.h b/src/core/lib/iomgr/tcp_server_utils_posix.h
index 608fba3346..6046f257f9 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix.h
+++ b/src/core/lib/iomgr/tcp_server_utils_posix.h
@@ -24,10 +24,6 @@
#include "src/core/lib/iomgr/socket_utils_posix.h"
#include "src/core/lib/iomgr/tcp_server.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* one listening port */
typedef struct grpc_tcp_listener {
int fd;
@@ -121,8 +117,4 @@ grpc_error* grpc_tcp_server_prepare_socket(int fd,
/* Ruturn true if the platform supports ifaddrs */
bool grpc_tcp_server_have_ifaddrs(void);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H */
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
index 72443cc29e..5139760634 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
@@ -55,7 +55,7 @@ static void init_max_accept_queue_size(void) {
if (fgets(buf, sizeof buf, fp)) {
char* end;
long i = strtol(buf, &end, 10);
- if (i > 0 && i <= INT_MAX && end && *end == 0) {
+ if (i > 0 && i <= INT_MAX && end && *end == '\n') {
n = (int)i;
}
}
diff --git a/src/core/lib/iomgr/tcp_uv.h b/src/core/lib/iomgr/tcp_uv.h
index 4b4da3608f..fd6d19049a 100644
--- a/src/core/lib/iomgr/tcp_uv.h
+++ b/src/core/lib/iomgr/tcp_uv.h
@@ -42,18 +42,10 @@ extern grpc_core::TraceFlag grpc_tcp_trace;
#define GRPC_TCP_DEFAULT_READ_SLICE_SIZE 8192
-#ifdef __cplusplus
-extern "C" {
-#endif
-
grpc_endpoint* grpc_tcp_create(uv_tcp_t* handle,
grpc_resource_quota* resource_quota,
char* peer_string);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_UV */
#endif /* GRPC_CORE_LIB_IOMGR_TCP_UV_H */
diff --git a/src/core/lib/iomgr/tcp_windows.h b/src/core/lib/iomgr/tcp_windows.h
index 9c7ccdf132..28287e2795 100644
--- a/src/core/lib/iomgr/tcp_windows.h
+++ b/src/core/lib/iomgr/tcp_windows.h
@@ -35,10 +35,6 @@
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/socket_windows.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Create a tcp endpoint given a winsock handle.
* Takes ownership of the handle.
*/
@@ -48,10 +44,6 @@ grpc_endpoint* grpc_tcp_create(grpc_exec_ctx* exec_ctx, grpc_winsocket* socket,
grpc_error* grpc_tcp_prepare_socket(SOCKET sock);
-#ifdef __cplusplus
-}
-#endif
-
#endif
#endif /* GRPC_CORE_LIB_IOMGR_TCP_WINDOWS_H */
diff --git a/src/core/lib/iomgr/time_averaged_stats.h b/src/core/lib/iomgr/time_averaged_stats.h
index d38ed272b6..8745f7fa13 100644
--- a/src/core/lib/iomgr/time_averaged_stats.h
+++ b/src/core/lib/iomgr/time_averaged_stats.h
@@ -19,10 +19,6 @@
#ifndef GRPC_CORE_LIB_IOMGR_TIME_AVERAGED_STATS_H
#define GRPC_CORE_LIB_IOMGR_TIME_AVERAGED_STATS_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* This tracks a time-decaying weighted average. It works by collecting
batches of samples and then mixing their average into a time-decaying
weighted mean. It is designed for batch operations where we do many adds
@@ -74,8 +70,4 @@ void grpc_time_averaged_stats_add_sample(grpc_time_averaged_stats* stats,
value. */
double grpc_time_averaged_stats_update_average(grpc_time_averaged_stats* stats);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_TIME_AVERAGED_STATS_H */
diff --git a/src/core/lib/iomgr/timer.h b/src/core/lib/iomgr/timer.h
index cd8334eceb..b9acce229e 100644
--- a/src/core/lib/iomgr/timer.h
+++ b/src/core/lib/iomgr/timer.h
@@ -32,10 +32,6 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/iomgr.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct grpc_timer grpc_timer;
/* Initialize *timer. When expired or canceled, closure will be called with
@@ -106,8 +102,4 @@ void grpc_timer_consume_kick(void);
void grpc_kick_poller(void);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_TIMER_H */
diff --git a/src/core/lib/iomgr/timer_heap.h b/src/core/lib/iomgr/timer_heap.h
index ae56e5a73e..436eef55a6 100644
--- a/src/core/lib/iomgr/timer_heap.h
+++ b/src/core/lib/iomgr/timer_heap.h
@@ -21,10 +21,6 @@
#include "src/core/lib/iomgr/timer.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct {
grpc_timer** timers;
uint32_t timer_count;
@@ -43,8 +39,4 @@ void grpc_timer_heap_pop(grpc_timer_heap* heap);
int grpc_timer_heap_is_empty(grpc_timer_heap* heap);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_TIMER_HEAP_H */
diff --git a/src/core/lib/iomgr/timer_manager.h b/src/core/lib/iomgr/timer_manager.h
index 72960d6ffc..0ba502928a 100644
--- a/src/core/lib/iomgr/timer_manager.h
+++ b/src/core/lib/iomgr/timer_manager.h
@@ -21,10 +21,6 @@
#include <stdbool.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Timer Manager tries to keep one thread waiting for the next timeout at all
times */
@@ -38,8 +34,4 @@ void grpc_timer_manager_set_threading(bool enabled);
* disabled */
void grpc_timer_manager_tick(void);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_TIMER_MANAGER_H */
diff --git a/src/core/lib/iomgr/udp_server.cc b/src/core/lib/iomgr/udp_server.cc
index 68ab9355ca..7b7d6946b1 100644
--- a/src/core/lib/iomgr/udp_server.cc
+++ b/src/core/lib/iomgr/udp_server.cc
@@ -47,6 +47,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/ev_posix.h"
+#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -71,14 +72,22 @@ struct grpc_udp_listener {
grpc_udp_server_read_cb read_cb;
grpc_udp_server_write_cb write_cb;
grpc_udp_server_orphan_cb orphan_cb;
+ // To be scheduled on another thread to actually read/write.
+ grpc_closure do_read_closure;
+ grpc_closure do_write_closure;
+ grpc_closure notify_on_write_closure;
// True if orphan_cb is trigered.
bool orphan_notified;
+ // True if grpc_fd_notify_on_write() is called after on_write() call.
+ bool notify_on_write_armed;
+ // True if fd has been shutdown.
+ bool already_shutdown;
struct grpc_udp_listener* next;
};
struct shutdown_fd_args {
- grpc_fd* fd;
+ grpc_udp_listener* sp;
gpr_mu* server_mu;
};
@@ -144,8 +153,17 @@ grpc_udp_server* grpc_udp_server_create(const grpc_channel_args* args) {
static void shutdown_fd(grpc_exec_ctx* exec_ctx, void* args,
grpc_error* error) {
struct shutdown_fd_args* shutdown_args = (struct shutdown_fd_args*)args;
+ grpc_udp_listener* sp = shutdown_args->sp;
+ gpr_log(GPR_DEBUG, "shutdown fd %d", sp->fd);
gpr_mu_lock(shutdown_args->server_mu);
- grpc_fd_shutdown(exec_ctx, shutdown_args->fd, GRPC_ERROR_REF(error));
+ grpc_fd_shutdown(exec_ctx, sp->emfd, GRPC_ERROR_REF(error));
+ sp->already_shutdown = true;
+ if (!sp->notify_on_write_armed) {
+ // Re-arm write notification to notify listener with error. This is
+ // necessary to decrement active_ports.
+ sp->notify_on_write_armed = true;
+ grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
+ }
gpr_mu_unlock(shutdown_args->server_mu);
gpr_free(shutdown_args);
}
@@ -161,6 +179,7 @@ static void finish_shutdown(grpc_exec_ctx* exec_ctx, grpc_udp_server* s) {
gpr_mu_destroy(&s->mu);
+ gpr_log(GPR_DEBUG, "Destroy all listeners.");
while (s->head) {
grpc_udp_listener* sp = s->head;
s->head = sp->next;
@@ -207,9 +226,10 @@ static void deactivated_all_ports(grpc_exec_ctx* exec_ctx, grpc_udp_server* s) {
/* Call the orphan_cb to signal that the FD is about to be closed and
* should no longer be used. Because at this point, all listening ports
* have been shutdown already, no need to shutdown again.*/
- GRPC_CLOSURE_INIT(&sp->orphan_fd_closure, dummy_cb, sp->emfd,
+ GRPC_CLOSURE_INIT(&sp->orphan_fd_closure, dummy_cb, sp,
grpc_schedule_on_exec_ctx);
GPR_ASSERT(sp->orphan_cb);
+ gpr_log(GPR_DEBUG, "Orphan fd %d", sp->fd);
sp->orphan_cb(exec_ctx, sp->emfd, &sp->orphan_fd_closure,
sp->server->user_data);
}
@@ -233,13 +253,14 @@ void grpc_udp_server_destroy(grpc_exec_ctx* exec_ctx, grpc_udp_server* s,
s->shutdown_complete = on_done;
+ gpr_log(GPR_DEBUG, "start to destroy udp_server");
/* shutdown all fd's */
if (s->active_ports) {
for (sp = s->head; sp; sp = sp->next) {
GPR_ASSERT(sp->orphan_cb);
struct shutdown_fd_args* args =
(struct shutdown_fd_args*)gpr_malloc(sizeof(*args));
- args->fd = sp->emfd;
+ args->sp = sp;
args->server_mu = &s->mu;
GRPC_CLOSURE_INIT(&sp->orphan_fd_closure, shutdown_fd, args,
grpc_schedule_on_exec_ctx);
@@ -329,6 +350,28 @@ error:
return -1;
}
+static void do_read(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
+ grpc_udp_listener* sp = reinterpret_cast<grpc_udp_listener*>(arg);
+ GPR_ASSERT(sp->read_cb && error == GRPC_ERROR_NONE);
+ /* TODO: the reason we hold server->mu here is merely to prevent fd
+ * shutdown while we are reading. However, it blocks do_write(). Switch to
+ * read lock if available. */
+ gpr_mu_lock(&sp->server->mu);
+ /* Tell the registered callback that data is available to read. */
+ if (!sp->already_shutdown &&
+ sp->read_cb(exec_ctx, sp->emfd, sp->server->user_data)) {
+ /* There maybe more packets to read. Schedule read_more_cb_ closure to run
+ * after finishing this event loop. */
+ GRPC_CLOSURE_SCHED(exec_ctx, &sp->do_read_closure, GRPC_ERROR_NONE);
+ } else {
+ /* Finish reading all the packets, re-arm the notification event so we can
+ * get another chance to read. Or fd already shutdown, re-arm to get a
+ * notification with shutdown error. */
+ grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
+ }
+ gpr_mu_unlock(&sp->server->mu);
+}
+
/* event manager callback when reads are ready */
static void on_read(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
grpc_udp_listener* sp = (grpc_udp_listener*)arg;
@@ -343,13 +386,51 @@ static void on_read(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
}
return;
}
-
- /* Tell the registered callback that data is available to read. */
+ /* Read once. If there is more data to read, off load the work to another
+ * thread to finish. */
GPR_ASSERT(sp->read_cb);
- sp->read_cb(exec_ctx, sp->emfd, sp->server->user_data);
+ if (sp->read_cb(exec_ctx, sp->emfd, sp->server->user_data)) {
+ /* There maybe more packets to read. Schedule read_more_cb_ closure to run
+ * after finishing this event loop. */
+ GRPC_CLOSURE_INIT(&sp->do_read_closure, do_read, arg,
+ grpc_executor_scheduler(GRPC_EXECUTOR_LONG));
+ GRPC_CLOSURE_SCHED(exec_ctx, &sp->do_read_closure, GRPC_ERROR_NONE);
+ } else {
+ /* Finish reading all the packets, re-arm the notification event so we can
+ * get another chance to read. Or fd already shutdown, re-arm to get a
+ * notification with shutdown error. */
+ grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
+ }
+ gpr_mu_unlock(&sp->server->mu);
+}
+
+// Wrapper of grpc_fd_notify_on_write() with a grpc_closure callback interface.
+void fd_notify_on_write_wrapper(grpc_exec_ctx* exec_ctx, void* arg,
+ grpc_error* error) {
+ grpc_udp_listener* sp = reinterpret_cast<grpc_udp_listener*>(arg);
+ gpr_mu_lock(&sp->server->mu);
+ if (!sp->notify_on_write_armed) {
+ grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
+ sp->notify_on_write_armed = true;
+ }
+ gpr_mu_unlock(&sp->server->mu);
+}
- /* Re-arm the notification event so we get another chance to read. */
- grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
+static void do_write(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
+ grpc_udp_listener* sp = reinterpret_cast<grpc_udp_listener*>(arg);
+ gpr_mu_lock(&(sp->server->mu));
+ if (sp->already_shutdown) {
+ // If fd has been shutdown, don't write any more and re-arm notification.
+ grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
+ } else {
+ sp->notify_on_write_armed = false;
+ /* Tell the registered callback that the socket is writeable. */
+ GPR_ASSERT(sp->write_cb && error == GRPC_ERROR_NONE);
+ GRPC_CLOSURE_INIT(&sp->notify_on_write_closure, fd_notify_on_write_wrapper,
+ arg, grpc_schedule_on_exec_ctx);
+ sp->write_cb(exec_ctx, sp->emfd, sp->server->user_data,
+ &sp->notify_on_write_closure);
+ }
gpr_mu_unlock(&sp->server->mu);
}
@@ -367,12 +448,11 @@ static void on_write(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
return;
}
- /* Tell the registered callback that the socket is writeable. */
- GPR_ASSERT(sp->write_cb);
- sp->write_cb(exec_ctx, sp->emfd, sp->server->user_data);
+ /* Schedule actual write in another thread. */
+ GRPC_CLOSURE_INIT(&sp->do_write_closure, do_write, arg,
+ grpc_executor_scheduler(GRPC_EXECUTOR_LONG));
- /* Re-arm the notification event so we get another chance to write. */
- grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
+ GRPC_CLOSURE_SCHED(exec_ctx, &sp->do_write_closure, GRPC_ERROR_NONE);
gpr_mu_unlock(&sp->server->mu);
}
@@ -409,6 +489,7 @@ static int add_socket_to_server(grpc_udp_server* s, int fd,
sp->write_cb = write_cb;
sp->orphan_cb = orphan_cb;
sp->orphan_notified = false;
+ sp->already_shutdown = false;
GPR_ASSERT(sp->emfd);
gpr_mu_unlock(&s->mu);
gpr_free(name);
@@ -533,6 +614,7 @@ void grpc_udp_server_start(grpc_exec_ctx* exec_ctx, grpc_udp_server* s,
GRPC_CLOSURE_INIT(&sp->write_closure, on_write, sp,
grpc_schedule_on_exec_ctx);
+ sp->notify_on_write_armed = true;
grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
/* Registered for both read and write callbacks: increment active_ports
diff --git a/src/core/lib/iomgr/udp_server.h b/src/core/lib/iomgr/udp_server.h
index bca0f049fb..1bd6922de6 100644
--- a/src/core/lib/iomgr/udp_server.h
+++ b/src/core/lib/iomgr/udp_server.h
@@ -23,10 +23,6 @@
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/resolve_address.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Forward decl of struct grpc_server */
/* This is not typedef'ed to avoid a typedef-redefinition error */
struct grpc_server;
@@ -34,13 +30,16 @@ struct grpc_server;
/* Forward decl of grpc_udp_server */
typedef struct grpc_udp_server grpc_udp_server;
-/* Called when data is available to read from the socket. */
-typedef void (*grpc_udp_server_read_cb)(grpc_exec_ctx* exec_ctx, grpc_fd* emfd,
+/* Called when data is available to read from the socket.
+ * Return true if there is more data to read from fd. */
+typedef bool (*grpc_udp_server_read_cb)(grpc_exec_ctx* exec_ctx, grpc_fd* emfd,
void* user_data);
-/* Called when the socket is writeable. */
+/* Called when the socket is writeable. The given closure should be scheduled
+ * when the socket becomes blocked next time. */
typedef void (*grpc_udp_server_write_cb)(grpc_exec_ctx* exec_ctx, grpc_fd* emfd,
- void* user_data);
+ void* user_data,
+ grpc_closure* notify_on_write_closure);
/* Called when the grpc_fd is about to be orphaned (and the FD closed). */
typedef void (*grpc_udp_server_orphan_cb)(grpc_exec_ctx* exec_ctx,
@@ -77,8 +76,4 @@ int grpc_udp_server_add_port(grpc_udp_server* s,
void grpc_udp_server_destroy(grpc_exec_ctx* exec_ctx, grpc_udp_server* server,
grpc_closure* on_done);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_UDP_SERVER_H */
diff --git a/src/core/lib/iomgr/unix_sockets_posix.h b/src/core/lib/iomgr/unix_sockets_posix.h
index be3c33d9c2..1c079e6e76 100644
--- a/src/core/lib/iomgr/unix_sockets_posix.h
+++ b/src/core/lib/iomgr/unix_sockets_posix.h
@@ -25,10 +25,6 @@
#include "src/core/lib/iomgr/resolve_address.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
void grpc_create_socketpair_if_unix(int sv[2]);
grpc_error* grpc_resolve_unix_domain_address(
@@ -42,8 +38,4 @@ void grpc_unlink_if_unix_domain_socket(
char* grpc_sockaddr_to_uri_unix_if_possible(
const grpc_resolved_address* resolved_addr);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_UNIX_SOCKETS_POSIX_H */
diff --git a/src/core/lib/iomgr/wakeup_fd_cv.h b/src/core/lib/iomgr/wakeup_fd_cv.h
index dcd7bdb560..017e41bfa8 100644
--- a/src/core/lib/iomgr/wakeup_fd_cv.h
+++ b/src/core/lib/iomgr/wakeup_fd_cv.h
@@ -40,10 +40,6 @@
#define GRPC_FD_TO_IDX(fd) (-(fd)-1)
#define GRPC_IDX_TO_FD(idx) (-(idx)-1)
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct cv_node {
gpr_cv* cv;
struct cv_node* next;
@@ -68,8 +64,4 @@ typedef struct cv_fd_table {
extern const grpc_wakeup_fd_vtable grpc_cv_wakeup_fd_vtable;
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H */
diff --git a/src/core/lib/iomgr/wakeup_fd_pipe.h b/src/core/lib/iomgr/wakeup_fd_pipe.h
index 9bbb5e2ff7..326a0c4e01 100644
--- a/src/core/lib/iomgr/wakeup_fd_pipe.h
+++ b/src/core/lib/iomgr/wakeup_fd_pipe.h
@@ -21,14 +21,6 @@
#include "src/core/lib/iomgr/wakeup_fd_posix.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
extern const grpc_wakeup_fd_vtable grpc_pipe_wakeup_fd_vtable;
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_WAKEUP_FD_PIPE_H */
diff --git a/src/core/lib/iomgr/wakeup_fd_posix.h b/src/core/lib/iomgr/wakeup_fd_posix.h
index ae7849f98c..a9584d0d48 100644
--- a/src/core/lib/iomgr/wakeup_fd_posix.h
+++ b/src/core/lib/iomgr/wakeup_fd_posix.h
@@ -49,10 +49,6 @@
#include "src/core/lib/iomgr/error.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
void grpc_wakeup_fd_global_init(void);
void grpc_wakeup_fd_global_destroy(void);
@@ -95,8 +91,4 @@ void grpc_wakeup_fd_destroy(grpc_wakeup_fd* fd_info);
* wakeup_fd_nospecial.c if no such implementation exists. */
extern const grpc_wakeup_fd_vtable grpc_specialized_wakeup_fd_vtable;
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_WAKEUP_FD_POSIX_H */