summaryrefslogtreecommitdiff
path: root/lib/tevent
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2022-07-13 12:30:47 +0000
committerJeremy Allison <jra@samba.org>2022-07-25 17:34:33 +0000
commit087b1b0efda81c89493a42debcaa9013ce60cfaf (patch)
treeaeb257dbfb73f5f862ad2ddda519684894d6c4fc /lib/tevent
parent8ff2fe33bdad605a2abfb5f3fac28b32f3211b96 (diff)
downloadsamba-087b1b0efda81c89493a42debcaa9013ce60cfaf.tar.gz
tevent: add tevent_cached_getpid() helper
This avoids a getpid() syscall per tevent_loop_once() iteration. We provide tevent_cached_getpid() also as helper for external consumers in order to have the logic only once. Note the change to ABI/tevent-0.12.1.sigs will be reverted with the bump to 0.13.0. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'lib/tevent')
-rw-r--r--lib/tevent/ABI/tevent-0.12.1.sigs1
-rw-r--r--lib/tevent/tevent.c41
-rw-r--r--lib/tevent/tevent.h16
-rw-r--r--lib/tevent/tevent_epoll.c7
-rw-r--r--lib/tevent/tevent_port.c7
5 files changed, 63 insertions, 9 deletions
diff --git a/lib/tevent/ABI/tevent-0.12.1.sigs b/lib/tevent/ABI/tevent-0.12.1.sigs
index 0e4d1e1fe26..68722a0e62f 100644
--- a/lib/tevent/ABI/tevent-0.12.1.sigs
+++ b/lib/tevent/ABI/tevent-0.12.1.sigs
@@ -22,6 +22,7 @@ _tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_conte
_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *)
tevent_abort: void (struct tevent_context *, const char *)
tevent_backend_list: const char **(TALLOC_CTX *)
+tevent_cached_getpid: pid_t (void)
tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *)
tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *)
tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *)
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index 81268a1bd7a..262fdaa22ed 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -199,6 +199,7 @@ static void tevent_common_wakeup_fini(struct tevent_context *ev);
static pthread_mutex_t tevent_contexts_mutex = PTHREAD_MUTEX_INITIALIZER;
static struct tevent_context *tevent_contexts = NULL;
static pthread_once_t tevent_atfork_initialized = PTHREAD_ONCE_INIT;
+static pid_t tevent_cached_global_pid = 0;
static void tevent_atfork_prepare(void)
{
@@ -263,6 +264,8 @@ static void tevent_atfork_child(void)
struct tevent_context *ev;
int ret;
+ tevent_cached_global_pid = getpid();
+
for (ev = DLIST_TAIL(tevent_contexts); ev != NULL;
ev = DLIST_PREV(ev)) {
struct tevent_threaded_context *tctx;
@@ -302,9 +305,41 @@ static void tevent_prep_atfork(void)
if (ret != 0) {
abort();
}
+
+ tevent_cached_global_pid = getpid();
+}
+
+#endif
+
+static int tevent_init_globals(void)
+{
+#ifdef HAVE_PTHREAD
+ int ret;
+
+ ret = pthread_once(&tevent_atfork_initialized, tevent_prep_atfork);
+ if (ret != 0) {
+ return ret;
+ }
+#endif
+
+ return 0;
}
+_PUBLIC_ pid_t tevent_cached_getpid(void)
+{
+#ifdef HAVE_PTHREAD
+ tevent_init_globals();
+#ifdef TEVENT_VERIFY_CACHED_GETPID
+ if (tevent_cached_global_pid != getpid()) {
+ tevent_abort(NULL, "tevent_cached_global_pid invalid");
+ }
+#endif
+ if (tevent_cached_global_pid != 0) {
+ return tevent_cached_global_pid;
+ }
#endif
+ return getpid();
+}
int tevent_common_context_destructor(struct tevent_context *ev)
{
@@ -434,13 +469,13 @@ static int tevent_common_context_constructor(struct tevent_context *ev)
{
int ret;
-#ifdef HAVE_PTHREAD
-
- ret = pthread_once(&tevent_atfork_initialized, tevent_prep_atfork);
+ ret = tevent_init_globals();
if (ret != 0) {
return ret;
}
+#ifdef HAVE_PTHREAD
+
ret = pthread_mutex_init(&ev->scheduled_mutex, NULL);
if (ret != 0) {
return ret;
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index 1c337adbf74..656df254be0 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -1909,6 +1909,22 @@ struct timeval tevent_timeval_add(const struct timeval *tv, uint32_t secs,
*/
struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs);
+/**
+ *
+ * @brief A cached version of getpid()
+ *
+ * We use getpid() in a lot a performance critical situations
+ * in order to check if caches are still valid in the current process.
+ *
+ * Calling getpid() always add the cost of an additional syscall!
+ *
+ * When tevent is build with pthread support, we already make use
+ * of pthread_atfork(), so it's trivial to use it maintain a cache for getpid().
+ *
+ * @return The pid of the current process.
+ */
+pid_t tevent_cached_getpid(void);
+
/* @} */
diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c
index 9cbe505c98a..1f1f47b2b21 100644
--- a/lib/tevent/tevent_epoll.c
+++ b/lib/tevent/tevent_epoll.c
@@ -206,7 +206,7 @@ static int epoll_init_ctx(struct epoll_event_context *epoll_ev)
"Failed to set close-on-exec, file descriptor may be leaked to children.\n");
}
- epoll_ev->pid = getpid();
+ epoll_ev->pid = tevent_cached_getpid();
talloc_set_destructor(epoll_ev, epoll_ctx_destructor);
return 0;
@@ -224,8 +224,9 @@ static void epoll_check_reopen(struct epoll_event_context *epoll_ev)
struct tevent_fd *fde;
bool *caller_panic_state = epoll_ev->panic_state;
bool panic_triggered = false;
+ pid_t pid = tevent_cached_getpid();
- if (epoll_ev->pid == getpid()) {
+ if (epoll_ev->pid == pid) {
return;
}
@@ -241,7 +242,7 @@ static void epoll_check_reopen(struct epoll_event_context *epoll_ev)
"Failed to set close-on-exec, file descriptor may be leaked to children.\n");
}
- epoll_ev->pid = getpid();
+ epoll_ev->pid = pid;
epoll_ev->panic_state = &panic_triggered;
for (fde=epoll_ev->ev->fd_events;fde;fde=fde->next) {
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
diff --git a/lib/tevent/tevent_port.c b/lib/tevent/tevent_port.c
index e91d442389d..ccb65a711b2 100644
--- a/lib/tevent/tevent_port.c
+++ b/lib/tevent/tevent_port.c
@@ -95,7 +95,7 @@ static int port_init_ctx(struct port_event_context *port_ev)
"Failed to set close-on-exec, file descriptor may be leaked to children.\n");
}
- port_ev->pid = getpid();
+ port_ev->pid = tevent_cached_getpid();
talloc_set_destructor(port_ev, port_ctx_destructor);
return 0;
@@ -199,8 +199,9 @@ static int port_update_event(struct port_event_context *port_ev, struct tevent_f
static int port_check_reopen(struct port_event_context *port_ev)
{
struct tevent_fd *fde;
+ pid_t pid = tevent_cached_getpid();
- if (port_ev->pid == getpid()) {
+ if (port_ev->pid == pid) {
return 0;
}
@@ -217,7 +218,7 @@ static int port_check_reopen(struct port_event_context *port_ev)
"Failed to set close-on-exec, file descriptor may be leaked to children.\n");
}
- port_ev->pid = getpid();
+ port_ev->pid = pid;
for (fde=port_ev->ev->fd_events;fde;fde=fde->next) {
fde->additional_flags &= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION;
if (port_update_event(port_ev, fde) != 0) {