[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/emacsql e9efb0803e 185/427: Oops, include the reap source.
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/emacsql e9efb0803e 185/427: Oops, include the reap source. |
Date: |
Tue, 13 Dec 2022 02:59:40 -0500 (EST) |
branch: elpa/emacsql
commit e9efb0803e2d9b5d310a1645a690973dd74ad73b
Author: Christopher Wellons <wellons@nullprogram.com>
Commit: Christopher Wellons <wellons@nullprogram.com>
Oops, include the reap source.
---
emacsql-reap.el | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/emacsql-reap.el b/emacsql-reap.el
new file mode 100644
index 0000000000..b076081f28
--- /dev/null
+++ b/emacsql-reap.el
@@ -0,0 +1,66 @@
+;;; emacsql-reap.el --- callbacks for garbage-collected objects -*-
lexical-binding: t; -*-
+
+;; This is free and unencumbered software released into the public domain.
+
+;; Commentary:
+
+;; This package is for immediately running a callback after a lisp
+;; object is garbage collected. An optional token can be passed to the
+;; callback to provide a hint as to what was collected, since the
+;; original object obviously can't be passed.
+
+;; It works by exploiting Emacs Lisp's weak hash tables and hooking
+;; the `post-gc-hook'.
+
+;;; Code:
+
+(require 'cl-lib)
+
+(defvar emacsql-reap-objects ()
+ "Collection of all objects being watched by the reaper.")
+
+(defun emacsql-reap--ref (thing)
+ "Create a weak reference to THING."
+ (let ((ref (make-hash-table :test 'eq :size 1 :weakness 'value)))
+ (prog1 ref
+ (setf (gethash t ref) thing))))
+
+(defun emacsql-reap--deref (ref)
+ "Retrieve value from REF."
+ (gethash t ref))
+
+(defun emacsql-reap--empty-p (ref)
+ "Return non-nil if value behind REF is still there."
+ (zerop (hash-table-count ref)))
+
+(cl-defun emacsql-reap-register (object callback &optional (token nil token-p))
+ "Run CALLBACK with TOKEN when OBJECT is garbage collected.
+Do *not* use OBJECT for TOKEN because it will not get collected."
+ (let ((ref (emacsql-reap--ref object))
+ (rich-token (and token-p (vector token))))
+ ;; Rich-token could be instead captured in a closure, but
+ ;; establishing a closure here would require this package to be
+ ;; byte-compiled in order to operate properly. Interpreted
+ ;; closures capture the entire environment.
+ (push (list callback rich-token ref) emacsql-reap-objects)))
+
+(defun emacsql-reap-single (entry)
+ "Cleanup ENTRY and return non-nil if ENTRY has been garbage collected."
+ (cl-destructuring-bind (callback token ref) entry
+ (when (emacsql-reap--empty-p ref)
+ (prog1 t
+ (ignore-errors
+ (if token
+ (funcall callback (elt token 0))
+ (funcall callback)))))))
+
+(defun emacsql-reap ()
+ "Run callbacks for garbage collected objects."
+ (setf emacsql-reap-objects
+ (cl-delete-if #'emacsql-reap-single emacsql-reap-objects)))
+
+(add-hook 'post-gc-hook #'emacsql-reap)
+
+(provide 'emacsql-reap)
+
+;;; emacsql-reap.el ends here
- [nongnu] elpa/emacsql 1d0ef4011c 167/427: Make emacsql-connection abstract., (continued)
- [nongnu] elpa/emacsql 1d0ef4011c 167/427: Make emacsql-connection abstract., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 64c3a03d62 169/427: Flesh out some more README., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 9f6c10eca0 172/427: Move error checking out to helper mix-in., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 4f76b94f7c 168/427: Set psql to print nil for NULL., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 7434263d82 174/427: Oops, drop leftover function call., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql ca62adc4b2 177/427: Add debug argument to emacsql-psql., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql afef528d81 179/427: Fix memoization to include type map., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql b2f2dd37cf 178/427: Allow connection to specify their own types., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 4aa889882d 182/427: Fix slot allocation on emacsql-connection., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 769abe20fa 183/427: Don't rely on a closure in cleanup hook., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql e9efb0803e 185/427: Oops, include the reap source.,
ELPA Syncer <=
- [nongnu] elpa/emacsql 5962268f83 184/427: Split off reaper code., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql f8c3d9fce2 369/427: Silence Emacs 25's byte-compiler, ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 8e34660ba1 370/427: Allow `gcc` as a separate option for C compilation., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 739c24cab6 389/427: Add kludge to work around `cl-defmethod' bug, ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 18b40213fd 403/427: No longer use obsolete generalized variable `point', ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 6d999ba39d 400/427: Update library headers, ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql a29b9e7ea5 388/427: No longer needlessly require url and url-http, ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 20e390ea06 401/427: Add FAQ to README.md, ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 30912aa69e 404/427: Include ../.config.mk in sqlite/Makefile, ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql f5da68e5f9 391/427: Fix quoting in docstring, ELPA Syncer, 2022/12/13