11import type { Env } from './env'
22import { Finalizer } from './Finalizer'
33import { RefTracker } from './RefTracker'
4- import { supportFinalizer } from './util'
54
65/** @internal */
76export interface RefBase extends Finalizer , RefTracker { }
87
8+ /** @public */
9+ export enum Ownership {
10+ kRuntime ,
11+ kUserland
12+ }
13+
914/** @internal */
1015export class RefBase extends Finalizer {
1116 public static finalizeAll ( list : RefTracker ) : void {
@@ -21,12 +26,12 @@ export class RefBase extends Finalizer {
2126 }
2227
2328 private _refcount : uint32_t
24- private _deleteSelf : boolean
29+ private readonly _ownership : Ownership
2530
2631 constructor (
2732 envObject : Env ,
2833 initial_refcount : uint32_t ,
29- delete_self : boolean ,
34+ ownership : Ownership ,
3035 finalize_callback : napi_finalize ,
3136 finalize_data : void_p ,
3237 finalize_hint : void_p
@@ -35,13 +40,14 @@ export class RefBase extends Finalizer {
3540 ; ( this as any ) . _next = null
3641 ; ( this as any ) . _prev = null
3742 this . _refcount = initial_refcount
38- this . _deleteSelf = delete_self
43+ this . _ownership = ownership
3944
4045 this . link ( ! finalize_callback ? envObject . reflist : envObject . finalizing_reflist )
4146 }
4247
4348 public dispose ( ) : void {
4449 this . unlink ( )
50+ this . envObject . dequeueFinalizer ( this )
4551 super . dispose ( )
4652 }
4753
@@ -64,39 +70,34 @@ export class RefBase extends Finalizer {
6470 return this . _refcount
6571 }
6672
67- public static doDelete ( reference : RefBase ) : void {
68- if ( ( reference . refCount ( ) !== 0 ) || ( reference . _deleteSelf ) ||
69- ( reference . _finalizeRan ) || ! supportFinalizer ) {
70- reference . dispose ( )
71- } else {
72- // defer until finalizer runs as
73- // it may already be queued
74- reference . _deleteSelf = true
75- }
73+ public ownership ( ) : Ownership {
74+ return this . _ownership
7675 }
7776
78- protected finalize ( isEnvTeardown = false ) : void {
79- if ( isEnvTeardown && this . refCount ( ) > 0 ) this . _refcount = 0
77+ public finalize ( ) : void {
78+ const ownership = this . _ownership
79+ // Swap out the field finalize_callback so that it can not be accidentally
80+ // called more than once.
81+ const finalize_callback = this . _finalizeCallback
82+ const finalize_data = this . _finalizeData
83+ const finalize_hint = this . _finalizeHint
84+ this . resetFinalizer ( )
85+
86+ this . unlink ( )
8087
8188 let error : any
8289 let caught = false
83- if ( this . _finalizeCallback ) {
84- const fini = Number ( this . _finalizeCallback )
85- this . _finalizeCallback = 0
90+ if ( finalize_callback ) {
91+ const fini = Number ( finalize_callback )
8692 try {
87- this . envObject . callFinalizer ( fini , this . _finalizeData , this . _finalizeHint )
93+ this . envObject . callFinalizer ( fini , finalize_data , finalize_hint )
8894 } catch ( err ) {
8995 caught = true
9096 error = err
9197 }
9298 }
93- if ( this . _deleteSelf || isEnvTeardown ) {
94- RefBase . doDelete ( this )
95- } else {
96- this . _finalizeRan = true
97- // leak if this is a non-self-delete weak reference
98- // should call napi_delete_referece manually
99- // Reference.doDelete(this)
99+ if ( ownership === Ownership . kRuntime ) {
100+ this . dispose ( )
100101 }
101102 if ( caught ) {
102103 throw error
0 commit comments