Subject: 28.0.50; Thread-Process Liberalization

From: [email-masked]
Date: Thu, 10 Jun 2021 16:36:34 -0400

Without this patch, threaded nnimap painfully starts a new imap connection
with every refresh.
>From 6e9c04f4cd6b45aec319dad9e3dea4b9ec034c6b Mon Sep 17 00:00:00 2001
From: dickmao <none>
Date: Thu, 10 Jun 2021 16:19:16 -0400
Subject: [PATCH] Lift a 2012 "process locked to thread" restriction

Remove an unexplained error that forbade a thread from
accepting output from a process it didn't start.

* src/process.c (Faccept_process_output): remove the error
(wait_reading_process_output): remove eassert to the same effect
* test/src/thread-tests.el (threads-test-channel): add
(threads-test-channel-send): add
(threads-test-channel-recv): add
(threads-signal-early): add
(threads-test-bug33073): add
(threads-test-bug36609-signal): add
(threads-test-glib-lock): add
(threads-test-promiscuous-process): add
---
 src/process.c            |  29 +---------
 test/src/thread-tests.el | 112 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 112 insertions(+), 29 deletions(-)

diff --git a/src/process.c b/src/process.c
index c354f3a90d..df6c8e38a6 100644
--- a/src/process.c
+++ b/src/process.c
@@ -4728,27 +4728,6 @@ DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_output,
   intmax_t secs;
   int nsecs;
 
-  if (! NILP (process))
-    {
-      CHECK_PROCESS (process);
-      struct Lisp_Process *proc = XPROCESS (process);
-
-      /* Can't wait for a process that is dedicated to a different
-	 thread.  */
-      if (!NILP (proc->thread) && !EQ (proc->thread, Fcurrent_thread ()))
-	{
-	  Lisp_Object proc_thread_name = XTHREAD (proc->thread)->name;
-
-	  error ("Attempt to accept output from process %s locked to thread %s",
-		 SDATA (proc->name),
-		 STRINGP (proc_thread_name)
-		 ? SDATA (proc_thread_name)
-		 : SDATA (Fprin1_to_string (proc->thread, Qt)));
-	}
-    }
-  else
-    just_this_one = Qnil;
-
   if (!NILP (millisec))
     { /* Obsolete calling convention using integers rather than floats.  */
       CHECK_FIXNUM (millisec);
@@ -4786,14 +4765,14 @@ DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_output,
       else
 	wrong_type_argument (Qnumberp, seconds);
     }
-  else if (! NILP (process))
+  else if (!NILP (process))
     nsecs = 0;
 
   return
     ((wait_reading_process_output (secs, nsecs, 0, 0,
 				   Qnil,
 				   !NILP (process) ? XPROCESS (process) : NULL,
-				   (NILP (just_this_one) ? 0
+				   ((NILP (process) || NILP (just_this_one)) ? 0
 				    : !FIXNUMP (just_this_one) ? 1 : -1))
       <= 0)
      ? Qnil : Qt);
@@ -5156,10 +5135,6 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
   /* Close to the current time if known, an invalid timespec otherwise.  */
   struct timespec now = invalid_timespec ();
 
-  eassert (wait_proc == NULL
-	   || NILP (wait_proc->thread)
-	   || XTHREAD (wait_proc->thread) == current_thread);
-
   FD_ZERO (&Available);
   FD_ZERO (&Writeok);
 
diff --git a/test/src/thread-tests.el b/test/src/thread-tests.el
index fc7bc7441b..6bafdb1d29 100644
--- a/test/src/thread-tests.el
+++ b/test/src/thread-tests.el
@@ -20,6 +20,8 @@
 ;;; Code:
 
 (require 'thread)
+(require 'eieio)
+(require 'ring)
 
 ;; Declare the functions in case Emacs has been configured --without-threads.
 (declare-function all-threads "thread.c" ())
@@ -42,6 +44,26 @@
 (declare-function thread-yield "thread.c" ())
 (defvar main-thread)
 
+(defclass threads-test-channel ()
+  ((condition :initarg :condition :type condition-variable)
+   (msg-queue :initarg :msg-queue :type ring)))
+
+(cl-defgeneric threads-test-channel-send ((channel threads-test-channel) message)
+  (with-slots (condition msg-queue) channel
+    (with-mutex (condition-mutex condition)
+      (while (<= (ring-size msg-queue) (ring-length msg-queue))
+        (condition-wait condition))
+      (ring-insert msg-queue message)
+      (condition-notify condition t))))
+
+(cl-defgeneric threads-test-channel-recv ((channel threads-test-channel))
+  (with-slots (condition msg-queue) channel
+    (with-mutex (condition-mutex condition)
+      (while (ring-empty-p msg-queue)
+        (condition-wait condition))
+      (prog1 (ring-remove msg-queue)
+        (condition-notify condition t)))))
+
 (ert-deftest threads-is-one ()
   "Test for existence of a thread."
   (skip-unless (featurep 'threads))
@@ -318,7 +340,7 @@ threads-signal-early
          (make-thread (lambda ()
                         (while t (thread-yield))))))
     (thread-signal thread 'error nil)
-    (sit-for 1)
+    (funcall (if noninteractive #'sit-for #'sleep-for) 1)
     (should-not (thread-live-p thread))
     (should (equal (thread-last-error) '(error)))))
 
@@ -389,7 +411,93 @@ threads-condvar-wait
     (should (equal (thread-last-error) '(error "Die, die, die!")))))
 
 (ert-deftest threads-test-bug33073 ()
+  (skip-unless (featurep 'threads))
   (let ((th (make-thread 'ignore)))
     (should-not (equal th main-thread))))
 
-;;; threads.el ends here
+(ert-deftest threads-test-bug36609-signal ()
+  "Would only fail under TEST_INTERACTIVE=yes, and not every time.
+The failure manifests only by being unable to exit the interactive emacs."
+  (skip-unless (featurep 'threads))
+  (let* ((cv (make-condition-variable (make-mutex) "CV"))
+       condition
+       (notify (lambda ()
+                 (sleep-for 1) ;; let wait() start spinning first
+                 (with-mutex (condition-mutex cv)
+                   (setq condition t)
+                   (condition-notify cv))))
+       (wait (lambda () (with-mutex (condition-mutex cv)
+                          (while (not condition)
+                            (condition-wait cv)))))
+       (herring (make-thread (apply-partially #'sleep-for 1000) "unrelated")))
+    ;; herring is a non-main thread that, if the bug is still present,
+    ;; could assume the glib context lock when the main thread executes wait()
+    (make-thread notify "notify")
+    (funcall wait)
+    (thread-signal herring 'quit nil)))
+
+(ert-deftest threads-test-glib-lock ()
+  "Would only fail under TEST_INTERACTIVE=yes, and not every time.
+The failure manifests only by being unable to exit the interactive emacs."
+  (skip-unless (featurep 'threads))
+  (cl-macrolet ((run-thread
+                 (name what)
+                 `(make-thread
+                   (lambda ()
+                     (sleep-for (1+ (random 3)))
+                     (funcall ,what))
+                   ,name)))
+    (let* ((n 3)
+           (capacity 1)
+           (channel (make-instance
+                     'threads-test-channel
+                     :condition (make-condition-variable (make-mutex) "channel")
+                     :msg-queue (make-ring capacity))))
+      (dotimes (i n)
+        (let ((send-name (format "send-%d" (1+ i)))
+	      (recv-name (format "recv-%d" (- n i))))
+          (run-thread send-name
+		      (lambda () (threads-test-channel-send channel 42)))
+          (run-thread recv-name
+		      (lambda () (threads-test-channel-recv channel))))))))
+
+(ert-deftest threads-test-promiscuous-process ()
+  "Can't we `accept-process-output' of a process started by another thread?
+For whatever reason, in 2012, tromey inserted an assertion forbidding this.
+We test flouting that edict here."
+  (skip-unless (featurep 'threads))
+  (thread-last-error t)
+  (let* ((thread-tests-main (get-buffer-create "thread-tests-main" t))
+         (buffers (list thread-tests-main))
+         (start-proc (lambda (n b)
+                       (apply #'start-process n b "cat" (split-string "/dev/urandom"))))
+         (n 3))
+    (funcall start-proc "threads-tests-main" (car buffers))
+    (dotimes (i (1- n))
+      (push (get-buffer-create (format "thread-tests-%d" i) t) buffers)
+      (make-thread (apply-partially start-proc
+                                    (format "thread-tests-%d" i)
+                                    (car buffers))))
+    (let ((procs (mapcar #'get-buffer-process buffers)))
+      (dotimes (i (1- n))
+        (make-thread
+         (lambda ()
+           (cl-loop repeat 5
+                    do (accept-process-output
+                        (nth (random (length procs)) procs)
+                        0.2
+                        nil
+                        t)))
+         (format "thread-tests-%d" i)))
+      (should (cl-loop repeat 20
+                       unless (cl-some
+                               (lambda (thr)
+                                 (cl-search "thread-tests-" (thread-name thr)))
+                               (all-threads))
+                       return t
+                       do (accept-process-output
+                           (nth (random (length procs)) procs) 1.0)
+                       finally return nil)))
+    (mapc (lambda (b) (kill-buffer b)) buffers))
+  (should-not (thread-last-error t)))
+;;; thread-tests.el ends here
-- 
2.26.2

In GNU Emacs 28.0.50 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.22.30, cairo version 1.15.10)
 of 2021-06-09 built on dick
Repository revision: 6dffe81dd7a91b6ed61e6e9a0e523587f394744c
Repository branch: gnus-dev-28
Windowing system distributor 'The X.Org Foundation', version 11.0.11906000
System Description: Ubuntu 18.04.4 LTS

Configured using:
 'configure --prefix=/home/dick/.local'
Configured features:
CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON LCMS2
LIBSELINUX LIBXML2 MODULES NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND
THREADS TIFF TOOLKIT_SCROLL_BARS X11 XDBE XIM XPM GTK3 ZLIB
Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: ELisp/d

Minor modes in effect:
  async-bytecomp-package-mode: t
  global-git-commit-mode: t
  magit-auto-revert-mode: t
  paredit-mode: t
  show-paren-mode: t
  projectile-mode: t
  flx-ido-mode: t
  override-global-mode: t
  shell-dirtrack-mode: t
  beacon-mode: t
  global-hl-line-mode: t
  winner-mode: t
  tooltip-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t

Load-path shadows:
/home/dick/ESS/lisp/obsolete/ess-swv hides /home/dick/ESS/lisp/ess-swv
/home/dick/ESS/lisp/obsolete/ess-rutils hides /home/dick/ESS/lisp/ess-rutils
/home/dick/ESS/lisp/obsolete/ess-noweb hides /home/dick/ESS/lisp/ess-noweb
/home/dick/ESS/lisp/obsolete/mouseme hides /home/dick/ESS/lisp/mouseme
/home/dick/ESS/lisp/obsolete/ess-mouse hides /home/dick/ESS/lisp/ess-mouse
/home/dick/ESS/lisp/obsolete/ess-noweb-mode hides /home/dick/ESS/lisp/ess-noweb-mode
/home/dick/ESS/lisp/obsolete/make-regexp hides /home/dick/ESS/lisp/make-regexp
/home/dick/ESS/lisp/obsolete/ess-r-a hides /home/dick/ESS/lisp/ess-r-a
/home/dick/ESS/lisp/obsolete/ess-noweb-font-lock-mode hides /home/dick/ESS/lisp/ess-noweb-font-lock-mode
/home/dick/gomacro-mode/gomacro-mode hides /home/dick/.emacs.d/elpa/gomacro-mode-20200326.1103/gomacro-mode
/home/dick/ESS/lisp/julia-mode hides /home/dick/.emacs.d/elpa/julia-mode-20200717.1915/julia-mode
/home/dick/ESS/lisp/julia-mode-latexsubs hides /home/dick/.emacs.d/elpa/julia-mode-20200717.1915/julia-mode-latexsubs
/home/dick/.emacs.d/elpa/hydra-20170924.2259/lv hides /home/dick/.emacs.d/elpa/lv-20191106.1238/lv
/home/dick/org-gcal.el/org-gcal hides /home/dick/.emacs.d/elpa/org-gcal-0.3/org-gcal
/home/dick/.emacs.d/elpa/async-20200113.1745/async-autoloads hides /home/dick/.local/share/emacs/site-lisp/emacs-async/async-autoloads
/home/dick/.emacs.d/elpa/async-20200113.1745/async-bytecomp hides /home/dick/.local/share/emacs/site-lisp/emacs-async/async-bytecomp
/home/dick/.emacs.d/elpa/async-20200113.1745/smtpmail-async hides /home/dick/.local/share/emacs/site-lisp/emacs-async/smtpmail-async
/home/dick/.emacs.d/elpa/async-20200113.1745/dired-async hides /home/dick/.local/share/emacs/site-lisp/emacs-async/dired-async
/home/dick/.emacs.d/elpa/async-20200113.1745/async hides /home/dick/.local/share/emacs/site-lisp/emacs-async/async
/home/dick/.emacs.d/elpa/async-20200113.1745/async-pkg hides /home/dick/.local/share/emacs/site-lisp/emacs-async/async-pkg
/home/dick/.emacs.d/lisp/json hides /home/dick/gnus/lisp/json
/home/dick/.emacs.d/elpa/transient-20210221.2251/transient hides /home/dick/gnus/lisp/transient
/home/dick/.emacs.d/elpa/org-9.4.5/ob-css hides /home/dick/gnus/lisp/org/ob-css
/home/dick/.emacs.d/elpa/org-9.4.5/ox-texinfo hides /home/dick/gnus/lisp/org/ox-texinfo
/home/dick/.emacs.d/elpa/org-9.4.5/org-plot hides /home/dick/gnus/lisp/org/org-plot
/home/dick/.emacs.d/elpa/org-9.4.5/ob-eval hides /home/dick/gnus/lisp/org/ob-eval
/home/dick/.emacs.d/elpa/org-9.4.5/ob-ref hides /home/dick/gnus/lisp/org/ob-ref
/home/dick/.emacs.d/elpa/org-9.4.5/org-crypt hides /home/dick/gnus/lisp/org/org-crypt
/home/dick/.emacs.d/elpa/org-9.4.5/ob-tangle hides /home/dick/gnus/lisp/org/ob-tangle
/home/dick/.emacs.d/elpa/org-9.4.5/ob-asymptote hides /home/dick/gnus/lisp/org/ob-asymptote
/home/dick/.emacs.d/elpa/org-9.4.5/ol-w3m hides /home/dick/gnus/lisp/org/ol-w3m
/home/dick/.emacs.d/elpa/org-9.4.5/ob-hledger hides /home/dick/gnus/lisp/org/ob-hledger
/home/dick/.emacs.d/elpa/org-9.4.5/ob-forth hides /home/dick/gnus/lisp/org/ob-forth
/home/dick/.emacs.d/elpa/org-9.4.5/org-mouse hides /home/dick/gnus/lisp/org/org-mouse
/home/dick/.emacs.d/elpa/org-9.4.5/org-indent hides /home/dick/gnus/lisp/org/org-indent
/home/dick/.emacs.d/elpa/org-9.4.5/org-attach-git hides /home/dick/gnus/lisp/org/org-attach-git
/home/dick/.emacs.d/elpa/org-9.4.5/org-element hides /home/dick/gnus/lisp/org/org-element
/home/dick/.emacs.d/elpa/org-9.4.5/ol-mhe hides /home/dick/gnus/lisp/org/ol-mhe
/home/dick/.emacs.d/elpa/org-9.4.5/org-footnote hides /home/dick/gnus/lisp/org/org-footnote
/home/dick/.emacs.d/elpa/org-9.4.5/ob-stan hides /home/dick/gnus/lisp/org/ob-stan
/home/dick/.emacs.d/elpa/org-9.4.5/ob-perl hides /home/dick/gnus/lisp/org/ob-perl
/home/dick/.emacs.d/elpa/org-9.4.5/org-timer hides /home/dick/gnus/lisp/org/org-timer
/home/dick/.emacs.d/elpa/org-9.4.5/org-table hides /home/dick/gnus/lisp/org/org-table
/home/dick/.emacs.d/elpa/org-9.4.5/org-keys hides /home/dick/gnus/lisp/org/org-keys
/home/dick/.emacs.d/elpa/org-9.4.5/org-colview hides /home/dick/gnus/lisp/org/org-colview
/home/dick/.emacs.d/elpa/org-9.4.5/ol hides /home/dick/gnus/lisp/org/ol
/home/dick/.emacs.d/elpa/org-9.4.5/org-entities hides /home/dick/gnus/lisp/org/org-entities
/home/dick/.emacs.d/elpa/org-9.4.5/org-src hides /home/dick/gnus/lisp/org/org-src
/home/dick/.emacs.d/elpa/org-9.4.5/ob-js hides /home/dick/gnus/lisp/org/ob-js
/home/dick/.emacs.d/elpa/org-9.4.5/org hides /home/dick/gnus/lisp/org/org
/home/dick/.emacs.d/elpa/org-9.4.5/ob-makefile hides /home/dick/gnus/lisp/org/ob-makefile
/home/dick/.emacs.d/elpa/org-9.4.5/ob-io hides /home/dick/gnus/lisp/org/ob-io
/home/dick/.emacs.d/elpa/org-9.4.5/org-refile hides /home/dick/gnus/lisp/org/org-refile
/home/dick/.emacs.d/elpa/org-9.4.5/org-clock hides /home/dick/gnus/lisp/org/org-clock
/home/dick/.emacs.d/elpa/org-9.4.5/ob-dot hides /home/dick/gnus/lisp/org/ob-dot
/home/dick/.emacs.d/elpa/org-9.4.5/ob-exp hides /home/dick/gnus/lisp/org/ob-exp
/home/dick/.emacs.d/elpa/org-9.4.5/org-compat hides /home/dick/gnus/lisp/org/org-compat
/home/dick/.emacs.d/elpa/org-9.4.5/ob-maxima hides /home/dick/gnus/lisp/org/ob-maxima
/home/dick/.emacs.d/elpa/org-9.4.5/ob-C hides /home/dick/gnus/lisp/org/ob-C
/home/dick/.emacs.d/elpa/org-9.4.5/org-tempo hides /home/dick/gnus/lisp/org/org-tempo
/home/dick/.emacs.d/elpa/org-9.4.5/ox-md hides /home/dick/gnus/lisp/org/ox-md
/home/dick/.emacs.d/elpa/org-9.4.5/ob-screen hides /home/dick/gnus/lisp/org/ob-screen
/home/dick/.emacs.d/elpa/org-9.4.5/ob-lua hides /home/dick/gnus/lisp/org/ob-lua
/home/dick/.emacs.d/elpa/org-9.4.5/ob-matlab hides /home/dick/gnus/lisp/org/ob-matlab
/home/dick/.emacs.d/elpa/org-9.4.5/ob-groovy hides /home/dick/gnus/lisp/org/ob-groovy
/home/dick/.emacs.d/elpa/org-9.4.5/ol-docview hides /home/dick/gnus/lisp/org/ol-docview
/home/dick/.emacs.d/elpa/org-9.4.5/ob-ebnf hides /home/dick/gnus/lisp/org/ob-ebnf
/home/dick/.emacs.d/elpa/org-9.4.5/ob-sed hides /home/dick/gnus/lisp/org/ob-sed
/home/dick/.emacs.d/elpa/org-9.4.5/ox-html hides /home/dick/gnus/lisp/org/ox-html
/home/dick/.emacs.d/elpa/org-9.4.5/ob-emacs-lisp hides /home/dick/gnus/lisp/org/ob-emacs-lisp
/home/dick/.emacs.d/elpa/org-9.4.5/ol-bbdb hides /home/dick/gnus/lisp/org/ol-bbdb
/home/dick/.emacs.d/elpa/org-9.4.5/org-macs hides /home/dick/gnus/lisp/org/org-macs
/home/dick/.emacs.d/elpa/org-9.4.5/org-lint hides /home/dick/gnus/lisp/org/org-lint
/home/dick/.emacs.d/elpa/org-9.4.5/org-loaddefs hides /home/dick/gnus/lisp/org/org-loaddefs
/home/dick/.emacs.d/elpa/org-9.4.5/ob-scheme hides /home/dick/gnus/lisp/org/ob-scheme
/home/dick/.emacs.d/elpa/org-9.4.5/org-protocol hides /home/dick/gnus/lisp/org/org-protocol
/home/dick/.emacs.d/elpa/org-9.4.5/ol-eww hides /home/dick/gnus/lisp/org/ol-eww
/home/dick/.emacs.d/elpa/org-9.4.5/ox-beamer hides /home/dick/gnus/lisp/org/ox-beamer
/home/dick/.emacs.d/elpa/org-9.4.5/ob-core hides /home/dick/gnus/lisp/org/ob-core
/home/dick/.emacs.d/elpa/org-9.4.5/org-agenda hides /home/dick/gnus/lisp/org/org-agenda
/home/dick/.emacs.d/elpa/org-9.4.5/ob-plantuml hides /home/dick/gnus/lisp/org/ob-plantuml
/home/dick/.emacs.d/elpa/org-9.4.5/ox-publish hides /home/dick/gnus/lisp/org/ox-publish
/home/dick/.emacs.d/elpa/org-9.4.5/ol-eshell hides /home/dick/gnus/lisp/org/ol-eshell
/home/dick/.emacs.d/elpa/org-9.4.5/ol-rmail hides /home/dick/gnus/lisp/org/ol-rmail
/home/dick/.emacs.d/elpa/org-9.4.5/ob-J hides /home/dick/gnus/lisp/org/ob-J
/home/dick/.emacs.d/elpa/org-9.4.5/ob-abc hides /home/dick/gnus/lisp/org/ob-abc
/home/dick/.emacs.d/elpa/org-9.4.5/ob-awk hides /home/dick/gnus/lisp/org/ob-awk
/home/dick/.emacs.d/elpa/org-9.4.5/ob-gnuplot hides /home/dick/gnus/lisp/org/ob-gnuplot
/home/dick/.emacs.d/elpa/org-9.4.5/ob-sql hides /home/dick/gnus/lisp/org/ob-sql
/home/dick/.emacs.d/elpa/org-9.4.5/ob-python hides /home/dick/gnus/lisp/org/ob-python
/home/dick/.emacs.d/elpa/org-9.4.5/ob-octave hides /home/dick/gnus/lisp/org/ob-octave
/home/dick/.emacs.d/elpa/org-9.4.5/ox-man hides /home/dick/gnus/lisp/org/ox-man
/home/dick/.emacs.d/elpa/org-9.4.5/ol-bibtex hides /home/dick/gnus/lisp/org/ol-bibtex
/home/dick/.emacs.d/elpa/org-9.4.5/org-goto hides /home/dick/gnus/lisp/org/org-goto
/home/dick/.emacs.d/elpa/org-9.4.5/ob-org hides /home/dick/gnus/lisp/org/ob-org
/home/dick/.emacs.d/elpa/org-9.4.5/ob-lob hides /home/dick/gnus/lisp/org/ob-lob
/home/dick/.emacs.d/elpa/org-9.4.5/ob-calc hides /home/dick/gnus/lisp/org/ob-calc
/home/dick/.emacs.d/elpa/org-9.4.5/org-macro hides /home/dick/gnus/lisp/org/org-macro
/home/dick/.emacs.d/elpa/org-9.4.5/ob hides /home/dick/gnus/lisp/org/ob
/home/dick/.emacs.d/elpa/org-9.4.5/ol-info hides /home/dick/gnus/lisp/org/ol-info
/home/dick/.emacs.d/elpa/org-9.4.5/ox-ascii hides /home/dick/gnus/lisp/org/ox-ascii
/home/dick/.emacs.d/elpa/org-9.4.5/ob-clojure hides /home/dick/gnus/lisp/org/ob-clojure
/home/dick/.emacs.d/elpa/org-9.4.5/org-inlinetask hides /home/dick/gnus/lisp/org/org-inlinetask
/home/dick/.emacs.d/elpa/org-9.4.5/ob-vala hides /home/dick/gnus/lisp/org/ob-vala
/home/dick/.emacs.d/elpa/org-9.4.5/ob-ruby hides /home/dick/gnus/lisp/org/ob-ruby
/home/dick/.emacs.d/elpa/org-9.4.5/ob-sass hides /home/dick/gnus/lisp/org/ob-sass
/home/dick/.emacs.d/elpa/org-9.4.5/org-faces hides /home/dick/gnus/lisp/org/org-faces
/home/dick/.emacs.d/elpa/org-9.4.5/org-attach hides /home/dick/gnus/lisp/org/org-attach
/home/dick/.emacs.d/elpa/org-9.4.5/ob-lilypond hides /home/dick/gnus/lisp/org/ob-lilypond
/home/dick/.emacs.d/elpa/org-9.4.5/org-archive hides /home/dick/gnus/lisp/org/org-archive
/home/dick/.emacs.d/elpa/org-9.4.5/ob-shen hides /home/dick/gnus/lisp/org/ob-shen
/home/dick/.emacs.d/elpa/org-9.4.5/org-datetree hides /home/dick/gnus/lisp/org/org-datetree
/home/dick/.emacs.d/elpa/org-9.4.5/org-id hides /home/dick/gnus/lisp/org/org-id
/home/dick/.emacs.d/elpa/org-9.4.5/ob-eshell hides /home/dick/gnus/lisp/org/ob-eshell
/home/dick/.emacs.d/elpa/org-9.4.5/ob-sqlite hides /home/dick/gnus/lisp/org/ob-sqlite
/home/dick/.emacs.d/elpa/org-9.4.5/ob-picolisp hides /home/dick/gnus/lisp/org/ob-picolisp
/home/dick/.emacs.d/elpa/org-9.4.5/org-habit hides /home/dick/gnus/lisp/org/org-habit
/home/dick/.emacs.d/elpa/org-9.4.5/org-ctags hides /home/dick/gnus/lisp/org/org-ctags
/home/dick/.emacs.d/elpa/org-9.4.5/ol-gnus hides /home/dick/gnus/lisp/org/ol-gnus
/home/dick/.emacs.d/elpa/org-9.4.5/ob-java hides /home/dick/gnus/lisp/org/ob-java
/home/dick/.emacs.d/elpa/org-9.4.5/ox-latex hides /home/dick/gnus/lisp/org/ox-latex
/home/dick/.emacs.d/elpa/org-9.4.5/org-pcomplete hides /home/dick/gnus/lisp/org/org-pcomplete
/home/dick/.emacs.d/elpa/org-9.4.5/ob-processing hides /home/dick/gnus/lisp/org/ob-processing
/home/dick/.emacs.d/elpa/org-9.4.5/ox-odt hides /home/dick/gnus/lisp/org/ox-odt
/home/dick/.emacs.d/elpa/org-9.4.5/org-feed hides /home/dick/gnus/lisp/org/org-feed
/home/dick/.emacs.d/elpa/org-9.4.5/ob-ditaa hides /home/dick/gnus/lisp/org/ob-ditaa
/home/dick/.emacs.d/elpa/org-9.4.5/ox-org hides /home/dick/gnus/lisp/org/ox-org
/home/dick/.emacs.d/elpa/org-9.4.5/ob-coq hides /home/dick/gnus/lisp/org/ob-coq
/home/dick/.emacs.d/elpa/org-9.4.5/ob-R hides /home/dick/gnus/lisp/org/ob-R
/home/dick/.emacs.d/elpa/org-9.4.5/ob-fortran hides /home/dick/gnus/lisp/org/ob-fortran
/home/dick/.emacs.d/elpa/org-9.4.5/ob-haskell hides /home/dick/gnus/lisp/org/ob-haskell
/home/dick/.emacs.d/elpa/org-9.4.5/ox-icalendar hides /home/dick/gnus/lisp/org/ox-icalendar
/home/dick/.emacs.d/elpa/org-9.4.5/org-num hides /home/dick/gnus/lisp/org/org-num
/home/dick/.emacs.d/elpa/org-9.4.5/ob-ledger hides /home/dick/gnus/lisp/org/ob-ledger
/home/dick/.emacs.d/elpa/org-9.4.5/ox hides /home/dick/gnus/lisp/org/ox
/home/dick/.emacs.d/elpa/org-9.4.5/org-mobile hides /home/dick/gnus/lisp/org/org-mobile
/home/dick/.emacs.d/elpa/org-9.4.5/org-duration hides /home/dick/gnus/lisp/org/org-duration
/home/dick/.emacs.d/elpa/org-9.4.5/org-list hides /home/dick/gnus/lisp/org/org-list
/home/dick/.emacs.d/elpa/org-9.4.5/ob-latex hides /home/dick/gnus/lisp/org/ob-latex
/home/dick/.emacs.d/elpa/org-9.4.5/ob-ocaml hides /home/dick/gnus/lisp/org/ob-ocaml
/home/dick/.emacs.d/elpa/org-9.4.5/ob-lisp hides /home/dick/gnus/lisp/org/ob-lisp
/home/dick/.emacs.d/elpa/org-9.4.5/ob-mscgen hides /home/dick/gnus/lisp/org/ob-mscgen
/home/dick/.emacs.d/elpa/org-9.4.5/ob-comint hides /home/dick/gnus/lisp/org/ob-comint
/home/dick/.emacs.d/elpa/org-9.4.5/org-capture hides /home/dick/gnus/lisp/org/org-capture
/home/dick/.emacs.d/elpa/org-9.4.5/ob-table hides /home/dick/gnus/lisp/org/ob-table
/home/dick/.emacs.d/elpa/org-9.4.5/ob-shell hides /home/dick/gnus/lisp/org/ob-shell
/home/dick/.emacs.d/elpa/org-9.4.5/ol-irc hides /home/dick/gnus/lisp/org/ol-irc
/home/dick/.emacs.d/elpa/org-9.4.5/org-version hides /home/dick/gnus/lisp/org/org-version
/home/dick/.emacs.d/elpa/hierarchy-20171221.1151/hierarchy hides /home/dick/gnus/lisp/emacs-lisp/hierarchy

Features:
(shadow emacsbug deuglify gnus-cus gnus-diary nndiary gnus-html gnus-logic
gnus-mh mh-comp mh-scan mh-gnus mh-e mh-compat mh-buffers mh-loaddefs
gnus-registry registry eieio-base gnus-salt gnus-uu yenc gnus-vm nnselect
gnus-search eww xdg supercite regi elpaso-disc web-server
web-server-status-codes ghub-graphql treepy gsexp ghub let-alist elpaso
elpaso-admin elpaso-milky elpaso-defs lisp-mnt magit-extras face-remap
magit-patch-changelog magit-patch magit-submodule magit-obsolete magit-popup
async-bytecomp async magit-blame magit-stash magit-reflog magit-bisect
magit-push magit-pull magit-fetch magit-clone magit-remote magit-commit
magit-sequence magit-notes magit-worktree magit-tag magit-merge magit-branch
magit-reset magit-files magit-refs magit-status magit magit-repos magit-apply
magit-wip magit-log magit-diff git-commit log-edit pcvs-util magit-core
magit-autorevert magit-margin magit-transient magit-process with-editor server
magit-mode transient magit-git magit-section magit-utils which-func imenu
url-queue dumb-jump f vc google-c-style pulse ffap edebug cl-print debug
backtrace canlock bbdb-message flyspell ispell footnote vc-git vc-dispatcher
bug-reference eieio-opt speedbar ezimage dframe shortdoc help-fns radix-tree
qp shr-color gravatar dns smerge-mode diff diff-mode misearch multi-isearch
nndoc debbugs-gnu add-log debbugs soap-client rng-xsd rng-dt rng-util
xsd-regexp sort smiley mm-archive mail-extr gnus-async gnus-ml
gnus-notifications gnus-fun notifications gnus-kill gnus-dup disp-table utf-7
gnutls network-stream url-cache nnfolder nnhackernews nntwitter benchmark
nntwitter-api bbdb-gnus gnus-demon nntp nnmairix nnml nnreddit gnus-topic
url-http url-auth url-gw nsm virtualenvwrapper gud s json-rpc python tramp-sh
tramp tramp-loaddefs trampver tramp-integration files-x tramp-compat ls-lisp
gnus-score score-mode gnus-bcklg gnus-srvr gnus-cite bbdb-mua bbdb-com crm
bbdb bbdb-site timezone gnus-delay gnus-draft gnus-cache gnus-agent gnus-msg
nndraft nnmh use-package use-package-delight use-package-diminish paredit-ext
paredit mu4e mu4e-org mu4e-main mu4e-view mu4e-view-gnus gnus-art mm-uu
mml2015 mm-view mml-smime smime dig mu4e-view-common mu4e-headers mu4e-compose
mu4e-context mu4e-draft mu4e-actions rfc2368 smtpmail sendmail mu4e-mark
mu4e-proc mu4e-utils doc-view jka-compr image-mode exif mu4e-lists
mu4e-message flow-fill org-tempo tempo org org-macro org-footnote
org-pcomplete org-list org-faces org-entities org-version ob-R ob-emacs-lisp
ob-ein ein-cell ein-output-area ein-kernel ein-ipdb ein-query ein-events
ein-websocket websocket bindat ein-node ewoc ein-log ein-classes ein-core
request autorevert filenotify ein ein-utils deferred cc-mode cc-fonts cc-guess
cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs ob ob-tangle
org-src ob-ref ob-lob ob-table ob-exp ob-comint ob-core ob-eval org-table ol
org-keys org-compat org-macs org-loaddefs find-func cal-menu calendar
cal-loaddefs gnus-sum shr kinsoku svg dom gnus-group mm-url gnus-undo
gnus-start gnus-dbus dbus xml gnus-cloud nnimap nnmail mail-source utf7 netrc
nnoo parse-time iso8601 gnus-spec gnus-int gnus-range gnus-win mule-util
mu4e-vars message rmc puny rfc822 mml mml-sec epa epg epg-config mm-decode
mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader
mu4e-meta subed subed-vtt subed-srt subed-common subed-mpv subed-debug
subed-config dired-x inf-ruby ruby-mode smie melpa-stats ht dash anaphora a
company haskell-interactive-mode haskell-presentation-mode haskell-process
haskell-session haskell-compile haskell-mode haskell-cabal haskell-utils
haskell-font-lock haskell-indentation haskell-string haskell-sort-imports
haskell-lexeme rx haskell-align-imports haskell-complete-module
haskell-ghc-support etags fileloop generator dabbrev haskell-customize hydra
lv use-package-ensure paren solarized-theme solarized-definitions projectile
skeleton ibuf-macs find-dired dired dired-loaddefs ibuf-ext ibuffer
ibuffer-loaddefs grep gnus nnheader gnus-util rmail rmail-loaddefs rfc2047
rfc2045 ietf-drums mm-util mail-prsvr mail-utils time-date flx-ido flx
google-translate-default-ui google-translate-core-ui facemenu color ido
google-translate-core google-translate-tk google-translate-backend
use-package-bind-key bind-key auto-complete advice popup cus-edit pp cus-load
wid-edit ess-r-mode ess-r-flymake flymake-proc flymake warnings thingatpt
ess-r-xref xref ess-trns ess-r-package shell pcomplete ess-r-completion
ess-roxy ess-r-syntax ess-rd noutline outline hideshow ess-s-lang ess-help
ess-mode ess-inf project format-spec ess-tracebug ess ess-utils ess-custom
compile text-property-search comint ansi-color emms-player-mplayer
emms-player-simple emms emms-compat cl-extra help-mode use-package-core
derived beacon easy-mmode pcase hl-line winner ring edmacro kmacro finder-inf
json-reformat-autoloads json-snatcher-autoloads sml-mode-autoloads
tornado-template-mode-autoloads info package browse-url url url-proxy
url-privacy url-expand url-methods url-history url-cookie url-domsuf url-util
mailcap url-handlers url-parse auth-source cl-seq eieio eieio-core cl-macs
eieio-loaddefs password-cache json subr-x map url-vars seq byte-opt gv
bytecomp byte-compile cconv cl-loaddefs cl-lib iso-transl tooltip eldoc
electric uniquify ediff-hook vc-hooks lisp-float-type mwheel term/x-win x-win
term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode elisp-mode lisp-mode prog-mode
register page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors frame
minibuffer cl-generic cham georgian utf-8-lang misc-lang vietnamese tibetan
thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek romanian
slovak czech european ethiopic indian cyrillic chinese composite charscript
charprop case-table epa-hook jka-cmpr-hook help simple abbrev obarray
cl-preloaded nadvice button loaddefs faces cus-face macroexp files window
text-properties overlay sha1 md5 base64 format env code-pages mule custom
widget hashtable-print-readable backquote threads dbusbind inotify lcms2
dynamic-setting system-font-setting font-render-setting cairo move-toolbar gtk
x-toolkit x multi-tty make-network-process emacs)

Memory information:
((conses 16 1966291 177326)
 (symbols 48 63774 69)
 (strings 32 318465 43584)
 (string-bytes 1 12735279)
 (vectors 16 81598)
 (vector-slots 8 1768056 231765)
 (floats 8 3308 1653)
 (intervals 56 13026 601)
 (buffers 992 53))