[rdnzl-devel] RDNZL - bug in delegate adapter release mechanism

Hi Edi I've tracked down what looks to be a bug in the mechanism for releasing delegate adapters. The foreign callable ReleaseDelegateAdapter is declared with a return type of ffi-void-pointer but tries to return the result of remhash - a boolean. On LWW (at least) this results in: Condition: T cannot be converted to foreign type :POINTER. Call to SYSTEM::FOREIGN-CALLABLE-ENTRY-POINT-NEW-PROCESS-AUX (offset 21) SYSTEM::FUNC : RDNZL::%FOREIGN-CALLABLE/RELEASEDELEGATEADAPTER I would suggest changing it (and the corresponding initialisation and DLL code) to have a void return type: (ffi-define-callable (ReleaseDelegateAdapter ffi-void) ((index ffi-integer)) ;; remove entry from hash table if CLR is done with it (remhash index *callback-hash*)) Also, in DelegateAdapter.cpp you have a comment on the destructor that it doesn't appear to be working: // the destructor notifies Lisp that this instance is no longer used - // at least in theory, this doesn't seem to work right now DelegateAdapter::~DelegateAdapter() { release(indexIntoLisp); } This may have beeen the caused by the callback/threading issues discussed recently. At least it has certainly worked for me here (hence this bug report) when using a DLL based LWW image (many thanks for your recent example of this). Perhaps the .NET GC is running in a different thread, so the callback was failing in a normal .EXE image? The full traceback from the bug above seems to support this - it shows LWW creating a new process to handle the callback: CL-USER 4 : 1 > :bb #<PACKAGE COMMON-LISP-USER> Condition: T cannot be converted to foreign type :POINTER. Call to SYSTEM::FOREIGN-CALLABLE-ENTRY-POINT-NEW-PROCESS-AUX (offset 21) SYSTEM::FUNC : RDNZL::%FOREIGN-CALLABLE/RELEASEDELEGATEADAPTER Catch frame: MP::PROCESS-TAG Catch frame: (NIL) Binding frame: MP:*CURRENT-PROCESS* : NIL Binding frame: WIN32::*DDE-THREAD-INSTANCE* : #<unbound> Binding frame: MQ::*ACTIONS-AFTER-SLEEPING* : NIL Binding frame: MR::*ACTIONS-BEFORE-SLEEPING* : NIL Binding frame: SYSTEM::*READER-STATE* : #<unbound> Binding frame: *PACKAGE* : #<PACKAGE COMMON-LISP-USER> Binding frame: EDITOR::*CURRENT-BUFFER* : NIL Binding frame: EDITOR::*CURRENT-WINDOW* : NIL Binding frame: EDITOR::*EDITOR-STATE* : NIL Binding frame: EDITOR::*EDITOR-INPUT-STYLE* : #S(EDITOR:EDITOR-INPUT- STYLE :KEY-BINDINGS #<EDITOR::KEY-TABLE #<EQUALP Hash Table{332} 20BCA90C> 1 331> :DELETE-SELECTION-MODE NIL :LOGICAL-CHARACTERS #<EQUALP Hash Table{21} 20C3D364> :EXECUTE-MODE #<EDITOR::MODE-OBJECT "Execute" 20CE37FC> :ECHO-MODE #<EDITOR::MODE-OBJECT "Echo Area" 20CE34A4> :PLIST NIL :INTERRUPT-KEYS (#S(SYSTEM::GESTURE-SPEC :DATA 103 :MODIFIERS 2) #S(SYSTEM::GESTURE-SPEC :DATA 71 :MODIFIERS 2)) :STYLE :EMACS :POINT-ALWAYS-VISIBLE T :USE-FACE-TO-FULL-WIDTH-P T) Binding frame: CAPI::*USE-ACCELERATORS* : T Binding frame: CAPI-WIN32-LIB::*ALT-IS-META-KEY* : T Catch frame: #:CATCHER100675 Call to (SUBFUNCTION MP::PROCESS-SG-FUNCTION MP::INITIALIZE-PROCESS- STACK) (offset 347) MS::IGNORED : :DONT-KNOW Catch frame: SYSTEM::EXIT-FOREIGN-CALLABLE Call to SYSTEM::FOREIGN-CALLABLE-ENTRY-POINT-NEW-PROCESS (offset 133) SYSTEM::FUNC : RDNZL::%FOREIGN-CALLABLE/RELEASEDELEGATEADAPTER Call to SYSTEM::%FUNCALL1-ON-LISP-STACK (offset 34) SYSTEM::%FUNCALL1-ON-LISP-STACK T - Dominic Robinson

Hi Dominic! On Fri, 13 Jan 2006 00:29:08 +0000, "lisp" <lisp@spikeisland.com> wrote:
I've tracked down what looks to be a bug in the mechanism for releasing delegate adapters.
The foreign callable ReleaseDelegateAdapter is declared with a return type of ffi-void-pointer but tries to return the result of remhash - a boolean. On LWW (at least) this results in:
Condition: T cannot be converted to foreign type :POINTER. Call to SYSTEM::FOREIGN-CALLABLE-ENTRY-POINT-NEW-PROCESS-AUX (offset 21) SYSTEM::FUNC : RDNZL::%FOREIGN-CALLABLE/RELEASEDELEGATEADAPTER
I would suggest changing it (and the corresponding initialisation and DLL code) to have a void return type:
(ffi-define-callable (ReleaseDelegateAdapter ffi-void) ((index ffi-integer)) ;; remove entry from hash table if CLR is done with it (remhash index *callback-hash*))
Also, in DelegateAdapter.cpp you have a comment on the destructor that it doesn't appear to be working:
// the destructor notifies Lisp that this instance is no longer used - // at least in theory, this doesn't seem to work right now DelegateAdapter::~DelegateAdapter() { release(indexIntoLisp); }
This may have beeen the caused by the callback/threading issues discussed recently. At least it has certainly worked for me here (hence this bug report) when using a DLL based LWW image (many thanks for your recent example of this). Perhaps the .NET GC is running in a different thread, so the callback was failing in a normal .EXE image?
Makes perfect sense to me. I've updated both the Lisp and the C++ code according to your recommendations - see ChangeLogs below. However, I'm a bit in a hurry and I couldn't figure out an easy example which shows that ReleaseDelegateAdapter is actually called - at least not from a DLL-based LWW image. Could you please check if it works and report back to the list if possible? Thanks a lot, Edi. Lisp code: ---------- Version 0.8.0 2006-01-13 Fix mechanism which releases delegate adapters (thanks to Dominic Robinson) Updated to DLL version 0.5.0 <http://weitz.de/files/RDNZL.tar.gz> C++ code (optional): -------------------- Version 0.5.0 2006-01-13 Fix mechanism which releases delegate adapters (thanks to Dominic Robinson) <http://weitz.de/files/RDNZL_cpp.tar.gz>
participants (2)
-
Edi Weitz
-
lisp