foreign: document internal make-late-will-executor
Also, rename from "stubborn" to "late" internally to be more consistent and avoid overloading "stubborn" in the allocator.
This commit is contained in:
parent
032479cf2c
commit
e13fac3ccf
|
@ -380,7 +380,7 @@ Registers a finalizer procedure @racket[finalizer-proc] with the given
|
|||
@racket[obj], which can be any Racket (GC-able) object. The finalizer
|
||||
is registered with a ``late'' @tech[#:doc reference.scrbl]{will
|
||||
executor} that makes wills ready for a value only after all
|
||||
@tech[#:doc reference.scrbl]{weak box}es referencing the value have
|
||||
weak references (such as in a @tech[#:doc reference.scrbl]{weak box}) for the value have
|
||||
been cleared, which implies that the value is unreachable and no
|
||||
normal @tech[#:doc reference.scrbl]{will executor} has a will ready
|
||||
for the value. The finalizer is invoked when the will for @racket[obj]
|
||||
|
|
|
@ -87,7 +87,24 @@ A curried variant of @racket[ffi-callback] that takes the callback procedure
|
|||
separately.}
|
||||
|
||||
|
||||
@defproc[(ffi-callback? [x any/c]) boolean?]{
|
||||
@defproc[(ffi-callback? [v any/c]) boolean?]{
|
||||
|
||||
A predicate for callback values that are created by @racket[ffi-callback].
|
||||
}
|
||||
|
||||
|
||||
@defproc[(make-late-will-executor) will-executor?]{
|
||||
|
||||
Creates a ``late'' will executor that readies a will for a value
|
||||
@scheme[_v] only if no normal will executor has a will registered for
|
||||
@scheme[_v]. In addition, weak references to @scheme[_v] are cleared
|
||||
before a will for @racket[_v] is readied by the late will
|
||||
executor.
|
||||
|
||||
Unlike a normal will executor, if a late will executor becomes
|
||||
inaccessible, the values for which it has pending wills are retained
|
||||
within the late will executor's place.
|
||||
|
||||
A late will executor is intended for use only in the implementation of
|
||||
@racket[register-finalizer]. See also @racket[make-late-weak-box] and
|
||||
@racket[make-late-weak-hasheq].}
|
||||
|
|
|
@ -2062,8 +2062,8 @@
|
|||
;; We bind `killer-executor' as a location variable, instead of a module
|
||||
;; variable, so that the loop for `killer-thread' doesn't have a namespace
|
||||
;; (via a prefix) in its continuation:
|
||||
(let ([killer-executor (make-stubborn-will-executor)])
|
||||
;; The "stubborn" kind of will executor (for `killer-executor') is
|
||||
(let ([killer-executor (make-late-will-executor)])
|
||||
;; The "late" kind of will executor (for `killer-executor') is
|
||||
;; provided by '#%foreign, and it doesn't get GC'ed if any
|
||||
;; finalizers are attached to it (while the normal kind can get
|
||||
;; GCed even if a thread that is otherwise inaccessible is blocked
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
[make-late-weak-box (known-procedure 2)]
|
||||
[make-late-weak-hasheq (known-procedure 1)]
|
||||
[make-sized-byte-string (known-procedure 4)]
|
||||
[make-stubborn-will-executor (known-procedure 1)]
|
||||
[make-late-will-executor (known-procedure 1)]
|
||||
[make-union-type (known-procedure -2)]
|
||||
[malloc (known-procedure 62)]
|
||||
[malloc-immobile-cell (known-procedure 2)]
|
||||
|
|
|
@ -476,7 +476,7 @@
|
|||
;; not the same as Racket will executors:
|
||||
(rename
|
||||
[make-will-executor rumble:make-will-executor]
|
||||
[make-stubborn-will-executor rumble:make-stubborn-will-executor]
|
||||
[make-late-will-executor rumble:make-late-will-executor]
|
||||
[will-executor? rumble:will-executor?]
|
||||
[will-register rumble:will-register]
|
||||
[will-try-execute rumble:will-try-execute])
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
;; for when a will becomes ready
|
||||
|
||||
(define-thread-local the-will-guardian (make-guardian))
|
||||
(define-thread-local the-stubborn-will-guardian (make-guardian #t))
|
||||
(define-thread-local the-late-will-guardian (make-guardian #t))
|
||||
|
||||
;; Guardian callbacks are called fifo, but will executors are called
|
||||
;; lifo. The `will-stacks` tables map a finalized value to a list
|
||||
|
@ -11,22 +11,22 @@
|
|||
;; executor with a will function (so that the function is not retained
|
||||
;; if the will executor is dropped)
|
||||
(define-thread-local the-will-stacks (make-weak-eq-hashtable))
|
||||
(define-thread-local the-stubborn-will-stacks (make-weak-eq-hashtable))
|
||||
(define-thread-local the-late-will-stacks (make-weak-eq-hashtable))
|
||||
|
||||
(define-thread-local stubborn-will-executors-with-pending (make-eq-hashtable))
|
||||
(define-thread-local late-will-executors-with-pending (make-eq-hashtable))
|
||||
|
||||
(define-record-type (will-executor create-will-executor will-executor?)
|
||||
(fields guardian will-stacks (mutable ready) notify stubborn?))
|
||||
(fields guardian will-stacks (mutable ready) notify late?))
|
||||
|
||||
(define (make-will-executor notify)
|
||||
(create-will-executor the-will-guardian the-will-stacks '() notify #f))
|
||||
|
||||
;; A "stubborn" will executor corresponds to an ordered guardian. It
|
||||
;; A "late" will executor corresponds to an ordered guardian. It
|
||||
;; doesn't need to make any guarantees about order for multiple
|
||||
;; registrations, so use a fresh guardian each time.
|
||||
;; A stubborn executor is treated a little specially in `will-register`.
|
||||
(define (make-stubborn-will-executor notify)
|
||||
(create-will-executor the-stubborn-will-guardian the-stubborn-will-stacks '() notify #t))
|
||||
;; A late executor is treated a little specially in `will-register`.
|
||||
(define (make-late-will-executor notify)
|
||||
(create-will-executor the-late-will-guardian the-late-will-stacks '() notify #t))
|
||||
|
||||
(define/who (will-register executor v proc)
|
||||
(check who will-executor? executor)
|
||||
|
@ -37,9 +37,9 @@
|
|||
;; unreachable, then we can drop the finalizer procedure. That
|
||||
;; pattern prevents unbreakable cycles by an untrusted process
|
||||
;; that has no access to a will executor that outlives the
|
||||
;; process. But stubborn will executors persist as long as
|
||||
;; process. But late will executors persist as long as
|
||||
;; a will is registered.
|
||||
[e+proc (if (will-executor-stubborn? executor)
|
||||
[e+proc (if (will-executor-late? executor)
|
||||
(cons executor proc)
|
||||
(ephemeron-cons executor proc))])
|
||||
(hashtable-set! (will-executor-will-stacks executor) v (cons e+proc l))
|
||||
|
@ -58,9 +58,9 @@
|
|||
(cond
|
||||
[(pair? l)
|
||||
(will-executor-ready-set! executor (cdr l))
|
||||
(when (and (will-executor-stubborn? executor)
|
||||
(when (and (will-executor-late? executor)
|
||||
(null? (cdr l)))
|
||||
(hashtable-delete! stubborn-will-executors-with-pending executor))
|
||||
(hashtable-delete! late-will-executors-with-pending executor))
|
||||
(enable-interrupts)
|
||||
(car l)]
|
||||
[else
|
||||
|
@ -95,12 +95,12 @@
|
|||
(guardian v)])
|
||||
((will-executor-notify e))
|
||||
(will-executor-ready-set! e (cons (cons proc v) (will-executor-ready e)))
|
||||
(when (will-executor-stubborn? e)
|
||||
;; Ensure that a stubborn will executor stays live
|
||||
(when (will-executor-late? e)
|
||||
;; Ensure that a late will executor stays live
|
||||
;; in this place as long as there are wills to execute
|
||||
(hashtable-set! stubborn-will-executors-with-pending e #t))]))))
|
||||
(hashtable-set! late-will-executors-with-pending e #t))]))))
|
||||
(loop)))))
|
||||
|
||||
(define (poll-will-executors)
|
||||
(poll-guardian the-will-guardian the-will-stacks)
|
||||
(poll-guardian the-stubborn-will-guardian the-stubborn-will-stacks))
|
||||
(poll-guardian the-late-will-guardian the-late-will-stacks))
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
'set-ctl-c-handler! rumble:set-ctl-c-handler!
|
||||
'poll-will-executors poll-will-executors
|
||||
'make-will-executor rumble:make-will-executor
|
||||
'make-stubborn-will-executor rumble:make-stubborn-will-executor
|
||||
'make-late-will-executor rumble:make-late-will-executor
|
||||
'will-executor? rumble:will-executor?
|
||||
'will-register rumble:will-register
|
||||
'will-try-execute rumble:will-try-execute
|
||||
|
|
|
@ -4743,11 +4743,11 @@ static Scheme_Object *foreign_lookup_errno(int argc, Scheme_Object *argv[])
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* (make-stubborn-will-executor) -> #<will-executor> */
|
||||
#define MYNAME "make-stubborn-will-executor"
|
||||
static Scheme_Object *foreign_make_stubborn_will_executor(int argc, Scheme_Object *argv[])
|
||||
/* (make-late-will-executor) -> #<will-executor> */
|
||||
#define MYNAME "make-late-will-executor"
|
||||
static Scheme_Object *foreign_make_late_will_executor(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
return scheme_make_stubborn_will_executor();
|
||||
return scheme_make_late_will_executor();
|
||||
}
|
||||
#undef MYNAME
|
||||
|
||||
|
@ -4988,8 +4988,8 @@ void scheme_init_foreign(Scheme_Startup_Env *env)
|
|||
scheme_make_immed_prim(foreign_saved_errno, "saved-errno", 0, 1), env);
|
||||
scheme_addto_prim_instance("lookup-errno",
|
||||
scheme_make_immed_prim(foreign_lookup_errno, "lookup-errno", 1, 1), env);
|
||||
scheme_addto_prim_instance("make-stubborn-will-executor",
|
||||
scheme_make_immed_prim(foreign_make_stubborn_will_executor, "make-stubborn-will-executor", 0, 0), env);
|
||||
scheme_addto_prim_instance("make-late-will-executor",
|
||||
scheme_make_immed_prim(foreign_make_late_will_executor, "make-late-will-executor", 0, 0), env);
|
||||
scheme_addto_prim_instance("make-late-weak-box",
|
||||
scheme_make_immed_prim(foreign_make_late_weak_box, "make-late-weak-box", 1, 1), env);
|
||||
scheme_addto_prim_instance("make-late-weak-hasheq",
|
||||
|
@ -5246,9 +5246,9 @@ static Scheme_Object *foreign_make_ctype(int argc, Scheme_Object **argv)
|
|||
return scheme_false;
|
||||
}
|
||||
|
||||
static Scheme_Object *foreign_make_stubborn_will_executor(int argc, Scheme_Object *argv[])
|
||||
static Scheme_Object *foreign_make_late_will_executor(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
return scheme_make_stubborn_will_executor();
|
||||
return scheme_make_late_will_executor();
|
||||
}
|
||||
|
||||
void scheme_init_foreign(Scheme_Env *env)
|
||||
|
@ -5353,8 +5353,8 @@ void scheme_init_foreign(Scheme_Env *env)
|
|||
scheme_make_immed_prim((Scheme_Prim *)unimplemented, "saved-errno", 0, 1), env);
|
||||
scheme_addto_primitive_instance("lookup-errno",
|
||||
scheme_make_immed_prim((Scheme_Prim *)unimplemented, "lookup-errno", 1, 1), env);
|
||||
scheme_addto_primitive_instance("make-stubborn-will-executor",
|
||||
scheme_make_immed_prim((Scheme_Prim *)foreign_make_stubborn_will_executor, "make-stubborn-will-executor", 0, 0), env);
|
||||
scheme_addto_primitive_instance("make-late-will-executor",
|
||||
scheme_make_immed_prim((Scheme_Prim *)foreign_make_late_will_executor, "make-late-will-executor", 0, 0), env);
|
||||
scheme_addto_primitive_instance("make-late-weak-box",
|
||||
scheme_make_immed_prim((Scheme_Prim *)unimplemented, "make-late-weak-box", 1, 1), env);
|
||||
scheme_addto_primitive_instance("make-late-weak-hasheq",
|
||||
|
|
|
@ -3660,9 +3660,9 @@ static void save_errno_values(int kind)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* (make-stubborn-will-executor) -> #<will-executor> */
|
||||
@cdefine[make-stubborn-will-executor 0 #:kind immed]{
|
||||
return scheme_make_stubborn_will_executor();
|
||||
/* (make-late-will-executor) -> #<will-executor> */
|
||||
@cdefine[make-late-will-executor 0 #:kind immed]{
|
||||
return scheme_make_late_will_executor();
|
||||
}
|
||||
|
||||
/* (make-late-weak-box val) -> #<weak-box> */
|
||||
|
@ -3830,15 +3830,15 @@ static Scheme_Object *foreign_make_ctype(int argc, Scheme_Object **argv)
|
|||
return scheme_false;
|
||||
}
|
||||
|
||||
static Scheme_Object *foreign_make_stubborn_will_executor(int argc, Scheme_Object *argv[])
|
||||
static Scheme_Object *foreign_make_late_will_executor(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
return scheme_make_stubborn_will_executor();
|
||||
return scheme_make_late_will_executor();
|
||||
}
|
||||
|
||||
@(define (lookup name)
|
||||
(if (member (cadr name) '("compiler_sizeof"
|
||||
"make_ctype"
|
||||
"make_stubborn_will_executor"))
|
||||
"make_late_will_executor"))
|
||||
name
|
||||
'unimplemented))
|
||||
|
||||
|
|
|
@ -256,7 +256,7 @@ typedef struct Thread_Local_Variables {
|
|||
struct Scheme_Config *initial_config_;
|
||||
struct Scheme_Thread *swap_target_;
|
||||
struct Scheme_Object *scheduled_kills_;
|
||||
struct Scheme_Hash_Table *stubborn_will_executors_with_pending_;
|
||||
struct Scheme_Hash_Table *late_will_executors_with_pending_;
|
||||
int do_atomic_;
|
||||
int missed_context_switch_;
|
||||
int all_breaks_disabled_;
|
||||
|
@ -641,7 +641,7 @@ XFORM_GC_VARIABLE_STACK_THROUGH_THREAD_LOCAL;
|
|||
#define initial_config XOA (scheme_get_thread_local_variables()->initial_config_)
|
||||
#define swap_target XOA (scheme_get_thread_local_variables()->swap_target_)
|
||||
#define scheduled_kills XOA (scheme_get_thread_local_variables()->scheduled_kills_)
|
||||
#define stubborn_will_executors_with_pending XOA (scheme_get_thread_local_variables()->stubborn_will_executors_with_pending_)
|
||||
#define late_will_executors_with_pending XOA (scheme_get_thread_local_variables()->late_will_executors_with_pending_)
|
||||
#define do_atomic XOA (scheme_get_thread_local_variables()->do_atomic_)
|
||||
#define missed_context_switch XOA (scheme_get_thread_local_variables()->missed_context_switch_)
|
||||
#define all_breaks_disabled XOA (scheme_get_thread_local_variables()->all_breaks_disabled_)
|
||||
|
|
|
@ -1142,7 +1142,7 @@ MZ_EXTERN Scheme_Object *scheme_make_ephemeron(Scheme_Object *key, Scheme_Object
|
|||
MZ_EXTERN Scheme_Object *scheme_ephemeron_value(Scheme_Object *o);
|
||||
MZ_EXTERN Scheme_Object *scheme_ephemeron_key(Scheme_Object *o);
|
||||
|
||||
MZ_EXTERN Scheme_Object *scheme_make_stubborn_will_executor();
|
||||
MZ_EXTERN Scheme_Object *scheme_make_late_will_executor();
|
||||
|
||||
MZ_EXTERN Scheme_Object *scheme_load(const char *file);
|
||||
MZ_EXTERN Scheme_Object *scheme_load_extension(const char *filename, Scheme_Env *env);
|
||||
|
|
|
@ -127,7 +127,7 @@ READ_ONLY static Scheme_Object *initial_inspector;
|
|||
|
||||
THREAD_LOCAL_DECL(static Scheme_Plumber *initial_plumber);
|
||||
|
||||
THREAD_LOCAL_DECL(static Scheme_Hash_Table *stubborn_will_executors_with_pending = NULL);
|
||||
THREAD_LOCAL_DECL(static Scheme_Hash_Table *late_will_executors_with_pending = NULL);
|
||||
|
||||
THREAD_LOCAL_DECL(Scheme_Config *initial_config);
|
||||
|
||||
|
@ -8647,7 +8647,7 @@ typedef struct WillExecutor {
|
|||
Scheme_Object so;
|
||||
Scheme_Object *sema;
|
||||
ActiveWill *first, *last;
|
||||
int is_stubborn;
|
||||
int is_late;
|
||||
} WillExecutor;
|
||||
|
||||
static void activate_will(void *o, void *data)
|
||||
|
@ -8679,14 +8679,14 @@ static void activate_will(void *o, void *data)
|
|||
w->last = a;
|
||||
scheme_post_sema(w->sema);
|
||||
|
||||
if (w->is_stubborn) {
|
||||
/* Ensure that a stubborn will executor stays live in this place
|
||||
if (w->is_late) {
|
||||
/* Ensure that a late will executor stays live in this place
|
||||
as long as there are wills to execute. */
|
||||
if (!stubborn_will_executors_with_pending) {
|
||||
REGISTER_SO(stubborn_will_executors_with_pending);
|
||||
stubborn_will_executors_with_pending = scheme_make_hash_table(SCHEME_hash_ptr);
|
||||
if (!late_will_executors_with_pending) {
|
||||
REGISTER_SO(late_will_executors_with_pending);
|
||||
late_will_executors_with_pending = scheme_make_hash_table(SCHEME_hash_ptr);
|
||||
}
|
||||
scheme_hash_set(stubborn_will_executors_with_pending, (Scheme_Object *)w, scheme_true);
|
||||
scheme_hash_set(late_will_executors_with_pending, (Scheme_Object *)w, scheme_true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8700,8 +8700,8 @@ static Scheme_Object *do_next_will(WillExecutor *w)
|
|||
w->first = a->next;
|
||||
if (!w->first) {
|
||||
w->last = NULL;
|
||||
if (w->is_stubborn)
|
||||
scheme_hash_set(stubborn_will_executors_with_pending, (Scheme_Object *)w, NULL);
|
||||
if (w->is_late)
|
||||
scheme_hash_set(late_will_executors_with_pending, (Scheme_Object *)w, NULL);
|
||||
}
|
||||
|
||||
o[0] = a->o;
|
||||
|
@ -8722,17 +8722,17 @@ static Scheme_Object *make_will_executor(int argc, Scheme_Object **argv)
|
|||
w->first = NULL;
|
||||
w->last = NULL;
|
||||
w->sema = sema;
|
||||
w->is_stubborn = 0;
|
||||
w->is_late = 0;
|
||||
|
||||
return (Scheme_Object *)w;
|
||||
}
|
||||
|
||||
Scheme_Object *scheme_make_stubborn_will_executor()
|
||||
Scheme_Object *scheme_make_late_will_executor()
|
||||
{
|
||||
WillExecutor *w;
|
||||
|
||||
w = (WillExecutor *)make_will_executor(0, NULL);
|
||||
w->is_stubborn = 1;
|
||||
w->is_late = 1;
|
||||
|
||||
return (Scheme_Object *)w;
|
||||
}
|
||||
|
@ -8752,7 +8752,7 @@ static Scheme_Object *register_will(int argc, Scheme_Object **argv)
|
|||
scheme_wrong_contract("will-register", "will-executor?", 0, argc, argv);
|
||||
scheme_check_proc_arity("will-register", 1, 2, argc, argv);
|
||||
|
||||
if (((WillExecutor *)argv[0])->is_stubborn) {
|
||||
if (((WillExecutor *)argv[0])->is_late) {
|
||||
e = scheme_make_pair(argv[0], argv[2]);
|
||||
scheme_add_finalizer(argv[1], activate_will, e);
|
||||
} else {
|
||||
|
|
|
@ -102,7 +102,7 @@
|
|||
[(custodian-shut-down? cust) #f]
|
||||
[else
|
||||
(define we (and (not weak?)
|
||||
(host:make-stubborn-will-executor void)))
|
||||
(host:make-late-will-executor void)))
|
||||
(hash-set! (custodian-children cust)
|
||||
obj
|
||||
(cond
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
[poll-will-executors host:poll-will-executors]
|
||||
[make-will-executor host:make-will-executor]
|
||||
[make-stubborn-will-executor host:make-stubborn-will-executor]
|
||||
[make-late-will-executor host:make-late-will-executor]
|
||||
[will-executor? host:will-executor?]
|
||||
[will-register host:will-register]
|
||||
[will-try-execute host:will-try-execute]
|
||||
|
|
|
@ -122,7 +122,7 @@
|
|||
custodian-shut-down?
|
||||
|
||||
make-will-executor
|
||||
make-stubborn-will-executor
|
||||
make-late-will-executor
|
||||
will-executor?
|
||||
will-register
|
||||
will-try-execute
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
;; `will-execute` here, because it has to block when no will is ready.
|
||||
|
||||
(provide make-will-executor
|
||||
make-stubborn-will-executor
|
||||
make-late-will-executor
|
||||
will-executor?
|
||||
will-register
|
||||
will-try-execute
|
||||
|
@ -35,8 +35,8 @@
|
|||
;; The returned wrapper will executor isn't necessarily retained when
|
||||
;; there are pending wills, but the underlying one is retained, and
|
||||
;; that implies that finalized values won't get lost
|
||||
(define (make-stubborn-will-executor)
|
||||
(do-make-will-executor host:make-stubborn-will-executor))
|
||||
(define (make-late-will-executor)
|
||||
(do-make-will-executor host:make-late-will-executor))
|
||||
|
||||
(define/who (will-register we v proc)
|
||||
(check who will-executor? we)
|
||||
|
|
Loading…
Reference in New Issue
Block a user