commit 1b2011ece96f265a3309a99227e5f287713cff83
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Wed Nov 4 01:02:49 2020 +0100

    AtSpi2: Drop X connection at fork without shutting down resources
    
    When cursor routing calls fork() and destructs the AtSpi2 driver,
    XCloseDisplay() would make the X server destruct all resources set up by
    the parent, thus crashing the parent. We can however easily just drop the X
    connection at fork.

diff --git a/Drivers/Screen/AtSpi2/a2_screen.c b/Drivers/Screen/AtSpi2/a2_screen.c
index 8fb6a9291..8bf6c1abc 100644
--- a/Drivers/Screen/AtSpi2/a2_screen.c
+++ b/Drivers/Screen/AtSpi2/a2_screen.c
@@ -1166,6 +1166,14 @@ void a2XSelUpdated(const char *data, unsigned long size) {
   setMainClipboardContent(content);
 }
 
+#ifdef HAVE_PTHREAD_ATFORK
+/* Drop X connection without shutting down its resources. Needed at fork. */
+void a2DropX(void) {
+  close(XConnectionNumber(dpy));
+  dpy = NULL;
+}
+#endif
+
 /* Called when X events are available, process them */
 ASYNC_MONITOR_CALLBACK(a2ProcessX) {
   XEvent ev;
@@ -1455,6 +1463,9 @@ construct_AtSpi2Screen (void) {
   if (dpy) {
     XSelInit(dpy, &xselData);
     XFlush(dpy);
+#ifdef HAVE_PTHREAD_ATFORK
+    pthread_atfork(NULL, NULL, a2DropX);
+#endif
     asyncMonitorFileInput(&a2XWatch, XConnectionNumber(dpy), a2ProcessX, NULL);
     coreSelUpdatedListener = registerReportListener(REPORT_API_PARAMETER_UPDATED, a2CoreSelUpdated , NULL);
   }
diff --git a/configure.ac b/configure.ac
index 4198a3d9a..d54f1b5dc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -856,6 +856,7 @@ BRLTTY_CHECK_FUNCTION([clock_gettime], [time.h], [rt])
 BRLTTY_CHECK_FUNCTION([clock_settime], [time.h], [rt])
 
 BRLTTY_CHECK_FUNCTION([pthread_getname_np], [pthread.h], [pthread])
+BRLTTY_CHECK_FUNCTION([pthread_atfork], [pthread.h], [pthread])
 
 AC_CHECK_DECLS([localtime_r], [], [], [dnl
 #include <time.h>
commit f98c3b1efe6d1e14bbcd6a8ef24b150492fa9eca
Author: Dave Mielke <Dave@Mielke.cc>
Date:   Wed Nov 4 00:09:18 2020 -0500

    Add HAVE_PTHREAD_ATFORK to config.h.in and add some #endif comments. (dm)

diff --git a/Drivers/Screen/AtSpi2/a2_screen.c b/Drivers/Screen/AtSpi2/a2_screen.c
index 79922dcaa..1aa6991d1 100644
--- a/Drivers/Screen/AtSpi2/a2_screen.c
+++ b/Drivers/Screen/AtSpi2/a2_screen.c
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_ATSPI_GET_A11Y_BUS
 #include <atspi/atspi.h>
-#endif
+#endif /* HAVE_ATSPI_GET_A11Y_BUS */
 
 #ifdef __MINGW32__
 #include "win_pthread.h"
@@ -1173,7 +1173,7 @@ void a2DropX(void) {
   close(XConnectionNumber(dpy));
   dpy = NULL;
 }
-#endif
+#endif /* HAVE_PTHREAD_ATFORK */
 
 /* Called when X events are available, process them */
 ASYNC_MONITOR_CALLBACK(a2ProcessX) {
@@ -1431,7 +1431,7 @@ construct_AtSpi2Screen (void) {
 #ifdef HAVE_ATSPI_GET_A11Y_BUS
   bus = atspi_get_a11y_bus();
   if (!bus)
-#endif
+#endif /* HAVE_ATSPI_GET_A11Y_BUS */
   {
     bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
     if (dbus_error_is_set(&error)) {
@@ -1467,7 +1467,7 @@ construct_AtSpi2Screen (void) {
     XFlush(dpy);
 #ifdef HAVE_PTHREAD_ATFORK
     pthread_atfork(NULL, NULL, a2DropX);
-#endif
+#endif /* HAVE_PTHREAD_ATFORK */
     asyncMonitorFileInput(&a2XWatch, XConnectionNumber(dpy), a2ProcessX, NULL);
     coreSelUpdatedListener = registerReportListener(REPORT_API_PARAMETER_UPDATED, a2CoreSelUpdated , NULL);
   }
diff --git a/config.h.in b/config.h.in
index 7b14484b6..cf860065b 100644
--- a/config.h.in
+++ b/config.h.in
@@ -125,6 +125,9 @@ extern "C" {
 /* Define this if the function pthread_getname_np exists. */
 #undef HAVE_PTHREAD_GETNAME_NP
 
+/* Define this if the function pthread_atfork exists. */
+#undef HAVE_PTHREAD_ATFORK
+
 /* Define this if the function nanosleep exists. */
 #undef HAVE_NANOSLEEP
 
