fix rktio destroy to release a pipe used for internal singals

Also, fix CS to desstroy a place's rktio instance when the place
exits.

Closes #3243
This commit is contained in:
Matthew Flatt 2020-06-09 10:04:46 -06:00
parent fcea8d3c67
commit 2768499b88
10 changed files with 51 additions and 6 deletions

View File

@ -0,0 +1,10 @@
#lang racket/base
(require racket/place)
;; Try to catch a resource leak starting and finishing places.
(for ([i (in-range 256)])
(printf "~s\n" i)
(map place-wait
(for/list ([i 4])
(dynamic-place ''#%kernel 'list))))

View File

@ -818,6 +818,9 @@
(lambda ()
(let ([f (dynamic-require mod sym)])
(f pch)))))
(set-destroy-place!
(lambda ()
(io-place-destroy!)))
(let ([a (or addon-dir
(getenv-bytes "PLTADDONDIR"))])

View File

@ -600,6 +600,7 @@
unsafe-extflvector-length unsafe-extflvector-ref unsafe-extflvector-set!
set-start-place! ; not exported to Racket
set-destroy-place! ; not exported to Racket
fork-place ; not exported to Racket
start-place ; not exported to Racket
place-enabled?

View File

@ -91,7 +91,8 @@
(set-box! place-esc-box esc)
(thunk)
0))])
(finish-proc result)))))
(finish-proc result)
(do-destroy-place)))))
;; Must be called within an engine, used for memory accounting:
(define (current-place-roots)
(list (place-registers)
@ -105,6 +106,10 @@
(define (set-start-place! proc)
(set! do-start-place proc))
(define do-destroy-place void)
(define (set-destroy-place! proc)
(set! do-destroy-place proc))
(define (start-place pch path sym in out err cust plumber)
(let ([finish (do-start-place pch path sym in out err cust plumber)])
(reset-async-callback-poll-wakeup!)

View File

@ -10,7 +10,8 @@
rktio-errno
rktio-errstep
racket-error?
rktio-place-init!)
rktio-place-init!
rktio-place-destroy!)
;; More `provide`s added by macros below
(define rktio-table
@ -82,5 +83,9 @@
(define (rktio-place-init!)
(set! rktio (rktio_init)))
(define (rktio-place-destroy!)
(rktio_destroy rktio)
(set! rktio #f))
;; Only in the main place:
(void (rktio_do_install_os_signal_handler rktio))

View File

@ -25,7 +25,8 @@
"port/parameter.rkt"
"path/system.rkt"
(only-in "host/rktio.rkt"
rktio-place-init!)
rktio-place-init!
rktio-place-destroy!)
(submod "error/main.rkt"
place-init)
(only-in "sandman/ltps.rkt"
@ -58,6 +59,7 @@
(all-from-out "run/main.rkt")
make-place-ports+fds
io-place-init!
io-place-destroy!
get-original-error-port)
(define (io-place-init! in-fd out-fd err-fd cust plumber)
@ -68,3 +70,8 @@
(install-error-value->string-handler!)
(init-current-directory!)
(init-current-ports! in-fd out-fd err-fd cust plumber))
(define (io-place-destroy!)
;; We expect everything based on rktio to be destroyed at this point
;; via custodian shutdown
(rktio-place-destroy!))

View File

@ -17,7 +17,7 @@
(values #f (dup-fd (fd-port-fd in) void "stdin dup"))
(reverse-pipe void "stdin pipe")))
(define (clean-in)
(rktio_close child-in-fd)
(rktio_close rktio child-in-fd)
(unless in
(rktio_close rktio parent-in-fd)))
(define-values (parent-out-fd child-out-fd)
@ -25,9 +25,9 @@
(values #f (dup-fd (fd-port-fd out) clean-in "stdout dup"))
(pipe clean-in "stdout pipe")))
(define (clean-out+in)
(rktio_close child-out-fd)
(rktio_close rktio child-out-fd)
(unless out
(rktio_close parent-out-fd))
(rktio_close rktio parent-out-fd))
(clean-in))
(define-values (parent-err-fd child-err-fd)
(if err

View File

@ -72,6 +72,7 @@ void rktio_destroy(rktio_t *rktio)
rktio_free_ghbn(rktio);
rktio_free_global_poll_set(rktio);
rktio_stop_fs_change(rktio);
rktio_free_signal(rktio);
#ifdef RKTIO_SYSTEM_WINDOWS
rktio_winsock_done(rktio);
#endif

View File

@ -1127,6 +1127,18 @@ int rktio_initialize_signal(rktio_t *rktio)
#endif
}
void rktio_free_signal(rktio_t *rktio)
{
#ifdef RKTIO_SYSTEM_UNIX
rktio_reliably_close(rktio->external_event_fd);
rktio_reliably_close(rktio->put_external_event_fd);
#endif
#ifdef RKTIO_SYSTEM_WINDOWS
CloseHandle(rktio->break_semaphore);
#endif
}
rktio_signal_handle_t *rktio_get_signal_handle(rktio_t *rktio)
{
#ifdef RKTIO_SYSTEM_UNIX

View File

@ -141,6 +141,7 @@ struct rktio_t {
void rktio_alloc_global_poll_set(rktio_t *rktio);
void rktio_free_global_poll_set(rktio_t *rktio);
int rktio_initialize_signal(rktio_t *rktio);
void rktio_free_signal(rktio_t *rktio);
#ifdef USE_FAR_RKTIO_FDCALLS