A try to fix automatic memory handling for LDAP structures.
- free ldap-messages of type result - free ldap-messages of type entry if and only if ldap_first_entry() converted from a result into an entry - don't free ldap-messages of type entry - entries depend on results, so don't free result before entries derived from it
This commit is contained in:
parent
55f238280a
commit
e236fbaec4
|
@ -72,6 +72,8 @@
|
||||||
ldap-message-c-pointer
|
ldap-message-c-pointer
|
||||||
ldap-message-session
|
ldap-message-session
|
||||||
set-ldap-message-session!
|
set-ldap-message-session!
|
||||||
|
ldap-message-result
|
||||||
|
set-ldap-message-result!
|
||||||
ldap-modification-c-pointer
|
ldap-modification-c-pointer
|
||||||
ldap-api-info-c-pointer
|
ldap-api-info-c-pointer
|
||||||
ber-element-c-pointer
|
ber-element-c-pointer
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
(display (number->string (ldap-message-c-pointer x) 16)))
|
(display (number->string (ldap-message-c-pointer x) 16)))
|
||||||
((ber-element? x)
|
((ber-element? x)
|
||||||
(display (number->string (ber-element-c-pointer x) 16)))
|
(display (number->string (ber-element-c-pointer x) 16)))
|
||||||
|
((ldap-session? x)
|
||||||
|
(display (number->string (ldap-session-c-pointer x) 16)))
|
||||||
(else
|
(else
|
||||||
(display x))))
|
(display x))))
|
||||||
lst)
|
lst)
|
||||||
|
@ -29,10 +31,11 @@
|
||||||
"scsh_ldap_memfree")
|
"scsh_ldap_memfree")
|
||||||
|
|
||||||
(define (ldap-session-finalizer session)
|
(define (ldap-session-finalizer session)
|
||||||
(ddisplay "Finalizing session" (ldap-session-c-pointer session))
|
(ddisplay "FREE ldap-session " session)
|
||||||
(if (ldap-session-bound? session)
|
(if (ldap-session-bound? session)
|
||||||
(if (not (ldap-session-implicit-unbind-ok? session))
|
(if (not (ldap-session-implicit-unbind-ok? session))
|
||||||
(raise (condition (&ldap-implicit-unbind (session session))))
|
(raise (condition
|
||||||
|
(&ldap-implicit-unbind (code #f) (session session))))
|
||||||
(if (ldap-session-auto-unbind? session)
|
(if (ldap-session-auto-unbind? session)
|
||||||
(ldap-unbind session))))
|
(ldap-unbind session))))
|
||||||
(remove-from-weak-table! *object-table* (ldap-session-c-pointer session))
|
(remove-from-weak-table! *object-table* (ldap-session-c-pointer session))
|
||||||
|
@ -93,7 +96,8 @@
|
||||||
server-controls client-controls
|
server-controls client-controls
|
||||||
credentials)
|
credentials)
|
||||||
(raise (condition (&ldap-bindings-not-implemented
|
(raise (condition (&ldap-bindings-not-implemented
|
||||||
(what '(ldap-sasl-bind ldap-controls))))))
|
(what '(ldap-sasl-bind ldap-controls))
|
||||||
|
(session #f) (code #f)))))
|
||||||
|
|
||||||
;;; UNBIND_S
|
;;; UNBIND_S
|
||||||
|
|
||||||
|
@ -124,12 +128,12 @@
|
||||||
"scsh_ldap_msgfree")
|
"scsh_ldap_msgfree")
|
||||||
|
|
||||||
(define (ldap-message-unregister-object message)
|
(define (ldap-message-unregister-object message)
|
||||||
(ddisplay "Message unregistering finalizer " (ldap-message-c-pointer message))
|
(ddisplay "UNREGISTER ldap-message " message)
|
||||||
(remove-from-weak-table! *object-table*
|
(remove-from-weak-table! *object-table*
|
||||||
(ldap-message-c-pointer message)))
|
(ldap-message-c-pointer message)))
|
||||||
|
|
||||||
(define (ldap-message-freeing-finalizer message)
|
(define (ldap-message-freeing-finalizer message)
|
||||||
(ddisplay "Message freeing finalizer " (ldap-message-c-pointer message))
|
(ddisplay "FREE ldap-message " message)
|
||||||
(ldap-message-unregister-object message)
|
(ldap-message-unregister-object message)
|
||||||
(ldap-msgfree message))
|
(ldap-msgfree message))
|
||||||
|
|
||||||
|
@ -166,6 +170,7 @@
|
||||||
(ddisplay "ldap-search new object " message)
|
(ddisplay "ldap-search new object " message)
|
||||||
(add-to-weak-table! *object-table* pointer message)
|
(add-to-weak-table! *object-table* pointer message)
|
||||||
(set-ldap-message-session! message session)
|
(set-ldap-message-session! message session)
|
||||||
|
(set-ldap-message-result! message #f)
|
||||||
(add-finalizer! message ldap-message-freeing-finalizer)
|
(add-finalizer! message ldap-message-freeing-finalizer)
|
||||||
message)))
|
message)))
|
||||||
(raise-ldap-condition ret-obj session))))))))
|
(raise-ldap-condition ret-obj session))))))))
|
||||||
|
@ -187,7 +192,8 @@
|
||||||
(if call-successful?
|
(if call-successful?
|
||||||
result
|
result
|
||||||
(raise
|
(raise
|
||||||
(condition (&ldap-session-option-error (session session)))))))))
|
(condition (&ldap-session-option-error
|
||||||
|
(code #f) (session session)))))))))
|
||||||
|
|
||||||
(define (ldap-session-option session-option . args)
|
(define (ldap-session-option session-option . args)
|
||||||
(let-optionals args ((session (current-ldap-session)))
|
(let-optionals args ((session (current-ldap-session)))
|
||||||
|
@ -200,7 +206,8 @@
|
||||||
(if call-successful?
|
(if call-successful?
|
||||||
result
|
result
|
||||||
(raise
|
(raise
|
||||||
(condition (&ldap-session-option-error (session session)))))))))
|
(condition (&ldap-session-option-error
|
||||||
|
(code #f) (session session)))))))))
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
|
|
||||||
|
@ -306,10 +313,9 @@
|
||||||
"scsh_ldap_ber_free")
|
"scsh_ldap_ber_free")
|
||||||
|
|
||||||
(define (ber-element-finalizer ber-element)
|
(define (ber-element-finalizer ber-element)
|
||||||
|
(ddisplay "FREE ber-element " ber-element)
|
||||||
(remove-from-weak-table!
|
(remove-from-weak-table!
|
||||||
*object-table* (ber-element-c-pointer ber-element))
|
*object-table* (ber-element-c-pointer ber-element))
|
||||||
(ddisplay "Freeing BerElement "
|
|
||||||
(ber-element-c-pointer ber-element))
|
|
||||||
(ber-element-free ber-element 1))
|
(ber-element-free ber-element 1))
|
||||||
|
|
||||||
(define (ldap-first-attribute entry . args)
|
(define (ldap-first-attribute entry . args)
|
||||||
|
@ -319,18 +325,15 @@
|
||||||
(apply values
|
(apply values
|
||||||
(ldap-first-attribute-internal session entry)))
|
(ldap-first-attribute-internal session entry)))
|
||||||
(lambda (attribute-name ber-element)
|
(lambda (attribute-name ber-element)
|
||||||
(ddisplay "ldap-first-attribute " entry)
|
|
||||||
(if attribute-name
|
(if attribute-name
|
||||||
(cond
|
(cond
|
||||||
((lookup-in-weak-table *object-table*
|
((lookup-in-weak-table *object-table*
|
||||||
(ber-element-c-pointer ber-element))
|
(ber-element-c-pointer ber-element))
|
||||||
=> (lambda (be)
|
=> (lambda (be)
|
||||||
(ddisplay "ldap-first-attribute ber-element known "
|
(ddisplay "RE ber-element (ldap-first-attribute) " be)
|
||||||
be)
|
|
||||||
(values attribute-name be)))
|
(values attribute-name be)))
|
||||||
(else
|
(else
|
||||||
(ddisplay "ldap-first-attribute ber-element unknown "
|
(ddisplay "NEW ber-element (ldap-first-attribute) " ber-element)
|
||||||
ber-element)
|
|
||||||
(add-finalizer! ber-element ber-element-finalizer)
|
(add-finalizer! ber-element ber-element-finalizer)
|
||||||
(values attribute-name ber-element)))
|
(values attribute-name ber-element)))
|
||||||
(raise-ldap-condition
|
(raise-ldap-condition
|
||||||
|
@ -462,21 +465,31 @@
|
||||||
(cond
|
(cond
|
||||||
((ldap-first-entry-internal session result)
|
((ldap-first-entry-internal session result)
|
||||||
=> (lambda (new-message)
|
=> (lambda (new-message)
|
||||||
(ddisplay "ldap-first-entry " result " " new-message)
|
|
||||||
(let ((pointer (ldap-message-c-pointer new-message)))
|
(let ((pointer (ldap-message-c-pointer new-message)))
|
||||||
(or (lookup-in-weak-table *object-table* pointer)
|
(cond
|
||||||
(begin
|
((lookup-in-weak-table *object-table* pointer)
|
||||||
(ddisplay "ldap-first-entry is new object")
|
=> (lambda (old-object)
|
||||||
;; don't add a finalizer in this case, because
|
(ddisplay "REUSE ldap-message as entry " old-object)
|
||||||
;; libldap will free the memory itself.
|
;; nomitated in the category "hack of the year"
|
||||||
(add-to-weak-table! *object-table* pointer new-message)
|
(set-ldap-message-result! old-object old-object)
|
||||||
(set-ldap-message-session! new-message session)
|
old-object))
|
||||||
new-message)))))
|
(else
|
||||||
(else
|
;; it's not certain that this code will ever be reached.
|
||||||
(let ((ret-obj (ldap-get-error-return-object session)))
|
;;
|
||||||
(if (ldap-success? ret-obj)
|
;; don't add a finalizer in this case, because
|
||||||
#f
|
;; libldap will free the memory itself.
|
||||||
(raise-ldap-condition ret-obj session)))))))
|
(ddisplay "NEW object (ldap-first-entry) result "
|
||||||
|
result " new-message " new-message)
|
||||||
|
(add-to-weak-table! *object-table* pointer new-message)
|
||||||
|
(set-ldap-message-session! new-message session)
|
||||||
|
(set-ldap-message-result! new-message result)
|
||||||
|
(add-finalizer! new-message ldap-message-unregister-object)
|
||||||
|
new-message))))
|
||||||
|
(else
|
||||||
|
(let ((ret-obj (ldap-get-error-return-object session)))
|
||||||
|
(if (ldap-success? ret-obj)
|
||||||
|
#f
|
||||||
|
(raise-ldap-condition ret-obj session))))))))
|
||||||
|
|
||||||
(define (ldap-next-entry entry . args)
|
(define (ldap-next-entry entry . args)
|
||||||
(let-optionals args ((session (current-ldap-session)))
|
(let-optionals args ((session (current-ldap-session)))
|
||||||
|
@ -486,10 +499,13 @@
|
||||||
(let ((pointer (ldap-message-c-pointer new-message)))
|
(let ((pointer (ldap-message-c-pointer new-message)))
|
||||||
(or (lookup-in-weak-table *object-table* pointer)
|
(or (lookup-in-weak-table *object-table* pointer)
|
||||||
(begin
|
(begin
|
||||||
|
(ddisplay "NEW message (ldap-next-entry) " new-message
|
||||||
|
" parent " (ldap-message-result entry))
|
||||||
;; don't add a finalizer in this case, because
|
;; don't add a finalizer in this case, because
|
||||||
;; libldap will free the memory itself.
|
;; libldap will free the memory itself.
|
||||||
(add-to-weak-table! *object-table* pointer new-message)
|
(add-to-weak-table! *object-table* pointer new-message)
|
||||||
(set-ldap-message-session! new-message session)
|
(set-ldap-message-session! new-message session)
|
||||||
|
(set-ldap-message-result! new-message (ldap-message-result entry))
|
||||||
(add-finalizer! new-message ldap-message-unregister-object)
|
(add-finalizer! new-message ldap-message-unregister-object)
|
||||||
new-message)))))
|
new-message)))))
|
||||||
(else
|
(else
|
||||||
|
|
|
@ -25,10 +25,13 @@
|
||||||
|
|
||||||
;;; This is the basic type
|
;;; This is the basic type
|
||||||
(define-record-type ldap-message :ldap-message
|
(define-record-type ldap-message :ldap-message
|
||||||
(make-ldap-message c-pointer session)
|
(make-ldap-message c-pointer session result)
|
||||||
ldap-message?
|
ldap-message?
|
||||||
(c-pointer ldap-message-c-pointer)
|
(c-pointer ldap-message-c-pointer)
|
||||||
(session ldap-message-session set-ldap-message-session!))
|
;; the following fields are needed to implement automatic
|
||||||
|
;; deallocation of ldap structures in C code
|
||||||
|
(session ldap-message-session set-ldap-message-session!)
|
||||||
|
(result ldap-message-result set-ldap-message-result!))
|
||||||
|
|
||||||
(define-exported-binding "ldap-message" :ldap-message)
|
(define-exported-binding "ldap-message" :ldap-message)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue