From 9b1db143283a96c548c33e04260e3379a2fbcebd Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 29 Jul 2012 06:52:47 -0600 Subject: [PATCH] ffi/com: fix clean-up of type descriptors Merge to v5.3 --- collects/ffi/unsafe/com.rkt | 57 ++++++++++++++++++++++------------- collects/tests/racket/com.rkt | 4 +++ 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/collects/ffi/unsafe/com.rkt b/collects/ffi/unsafe/com.rkt index 5fa6b43a22..190ed51e23 100644 --- a/collects/ffi/unsafe/com.rkt +++ b/collects/ffi/unsafe/com.rkt @@ -247,12 +247,21 @@ [(_ (#:release-with-method name) expr obj arg ...) (let ([self obj]) (((allocator (lambda (v) (name self v))) - expr) + (let ([f expr]) + (lambda args + (AddRef self) + (apply f args)))) self arg ...))] - [(_ (#:releases) expr arg ...) - (((deallocator cadr) expr) arg ...)])) - + [(_ (#:releases) expr obj arg ...) + (let ([self obj]) + (((deallocator cadr) + (let ([f expr]) + (lambda args + (Release self) + (apply f args)))) + self arg ...))])) + (define (check-com-type who id id? obj) (unless (id? obj) (raise-type-error who (symbol->string id) obj))) @@ -630,9 +639,27 @@ set-com-object-connection-point!) (bye! com-object-sink set-com-object-sink!) - (when (hash-count (com-object-types obj)) + (when (positive? (hash-count (com-object-types obj))) + (for ([td (in-hash-values (com-object-types obj))]) + '(release-type-desc td)) (set-com-object-types! obj (make-hash)))))) +(define (release-type-desc td) + ;; call in atomic mode + (define type-info (mx-com-type-desc-type-info td)) + (define type-info-impl (mx-com-type-desc-type-info-impl td)) + (define tdd (mx-com-type-desc-desc td)) + (cond + [(list? tdd) + (ReleaseFuncDesc type-info (car tdd)) + (when type-info-impl + (ReleaseFuncDesc type-info-impl (cadr tdd)))] + [else + (ReleaseVarDesc type-info tdd)]) + (Release type-info) + (when type-info-impl + (Release type-info-impl))) + (define (gen->clsid who name) (cond [(clsid? name) name] @@ -876,12 +903,9 @@ string-ci () string) (com-get-property-type doc "title")) (test '(-> (string) void) (com-set-property-type doc "title")) + (test (void) (com-set-property! ie "Visible" #t)) + (test (void) (com-invoke ie "Quit")) + + (test (void) (com-release doc)) (test (void) (com-release ie)) (test #t (type-description? 'int))