Hi Wizards,-------------------------------------------^
I am soooo desperate with the sample extension.
Standard functionality like the build-info and the dll unload feels so complicated. How can we put all this burden to the poor extension developpers?
Ok, enough moaning !
See here:
https://core.tcl-lang.org/sampleextension/info/2c5e0e025efd0b9f
The two commands sha1 and ::sha1::build-info are created in the init procedure.
They have to be deleted in the unload procedure.
How do I beam the two "tolkens" to the unload procedure ?
Sample_Init:
struct CmdClientData *cmdClientDataPtr;
cmdClientDataPtr = ckalloc(sizeof(struct Sha1ClientData));
cmdClientDataPtr->sha1CmdTolken = Tcl_CreateObjCommand(---------------^
interp, "sha1", (Tcl_ObjCmdProc *)Sha1_Cmd,
sha1ClientDataPtr, Sha1_CmdDeleteProc);
Sample_Unload:
??? How to get cmdClientDataPtr access here ??? Tcl_DeleteCommandFromToken(interp, cmdClientDataPtr->sha1CmdTolken); ckfree(cmdClientDataPtr);
And of cause, the git magic is not working for build-info - it does not build any more without git - info how this may work is nowhere...
But that is the next step.
Thanks for any idea!--
Harald
On Tue, 10 Dec 2024 10:35:46 +0100
Harald Oehlmann <wortkarg3@yahoo.com> wrote:
Hi Wizards,
I am soooo desperate with the sample extension.
Standard functionality like the build-info and the dll unload feels so
complicated. How can we put all this burden to the poor extension
developpers?
Ok, enough moaning !
See here:
https://core.tcl-lang.org/sampleextension/info/2c5e0e025efd0b9f
The two commands sha1 and ::sha1::build-info are created in the init
procedure.
They have to be deleted in the unload procedure.
How do I beam the two "tolkens" to the unload procedure ?
Sample_Init:-------------------------------------------^
struct CmdClientData *cmdClientDataPtr;
cmdClientDataPtr = ckalloc(sizeof(struct Sha1ClientData));
Shouldn't this be "struct CmdClientDataPtr"?
cmdClientDataPtr->sha1CmdTolken = Tcl_CreateObjCommand(---------------^
interp, "sha1", (Tcl_ObjCmdProc *)Sha1_Cmd,
sha1ClientDataPtr, Sha1_CmdDeleteProc);
Shouldn't this be "cmdClientDataPtr"?
Sample_Unload:
??? How to get cmdClientDataPtr access here ???
Tcl_DeleteCommandFromToken(interp, cmdClientDataPtr->sha1CmdTolken);
ckfree(cmdClientDataPtr);
You get (at least!) three "levels" for storing cliendata to Tcl:
* Per command, using the clientdata argument of Tcl_CreateObjCommand().
* Per interp, using Tcl_{Set|Get}AssocData().
* Per thread, using Tcl_GetThreadData().
In this case, Tcl_GetAssocData is to be used, since you want to wipe the command out from the current interpreter, leaving other interps alone.
A simple example (untested !!!)
#define MY_PKG_KEY "My great package key"
Tcl_InterpDeleteProc pkgInterpDeleted; /* called when the interp is deleted */
struct CmdClientData {
Tcl_Command sha1CmdToken;
};
Sample_Init:
struct CmdClientData *cmdClientDataPtr;
cmdClientDataPtr = ckalloc(sizeof(struct CmdClientData));
Tcl_SetAssocData(interp, MY_PKG_KEY, pkgInterpDeleted, cmdClientDataPtr);
cmdClientDataPtr->sha1CmdToken = Tcl_CreateObjCommand(
interp, "sha1", (Tcl_ObjCmdProc *)Sha1_Cmd,
cmdClientDataPtr, Sha1_CmdDeleteProc);
Sample_Unload:
struct CmdClientData *cmdClientDataPtr = (struct CmdClientData *)
Tcl_GetAssocData(interp, MY_PKG_KEY, NULL);
/* check whether the pointer is not NULL */
Tcl_DeleteCommandFromToken(interp, cmdClientDataPtr->sha1CmdToken);
ckfree(cmdClientDataPtr);
Tcl_DeleteAssocData(interp, MY_PKG_KEY);
Of course you have to juggle the interaction of Sample_Unload, Sha1CmdDeleteProc and pkgInterpDeleted, since they can be called when:
* [sha1] cmd is deleted (Sha1_CmdDeleteProc is called).
* interp is destroyed (pkgInterpDeleted is called).
* [unload] is called on the external library (Sample_Unload is called).
Hope this helps.
On Tue, 10 Dec 2024 10:35:46 +0100
Sample_Init:-------------------------------------------^
struct CmdClientData *cmdClientDataPtr;
cmdClientDataPtr = ckalloc(sizeof(struct Sha1ClientData));
Shouldn't this be "struct CmdClientDataPtr"?
cmdClientDataPtr->sha1CmdTolken = Tcl_CreateObjCommand(---------------^
interp, "sha1", (Tcl_ObjCmdProc *)Sha1_Cmd,
sha1ClientDataPtr, Sha1_CmdDeleteProc);
Shouldn't this be "cmdClientDataPtr"?
Am 10.12.2024 um 16:13 schrieb Emiliano:
On Tue, 10 Dec 2024 10:35:46 +0100
Sample_Init:-------------------------------------------^
struct CmdClientData *cmdClientDataPtr;
cmdClientDataPtr = ckalloc(sizeof(struct Sha1ClientData));
Shouldn't this be "struct CmdClientDataPtr"?
Yes, good catch
cmdClientDataPtr->sha1CmdTolken = Tcl_CreateObjCommand(---------------^
interp, "sha1", (Tcl_ObjCmdProc *)Sha1_Cmd,
sha1ClientDataPtr, Sha1_CmdDeleteProc);
Shouldn't this be "cmdClientDataPtr"?
Well, I use a client data for the command "sha1ClientDataPtr" with the command state, which is deleted by the command delete proc "Sha1_CmdDeleteProc".
In addition, there is assoc data of the dll "cmdClientDataPtr" to keep
the command tokens for removal within the unload procedure.
Is this design sensible ?
THanks for all,
Harald
On Tue, 10 Dec 2024 17:11:08 +0100
Harald Oehlmann <wortkarg3@yahoo.com> wrote:
Am 10.12.2024 um 16:13 schrieb Emiliano:
On Tue, 10 Dec 2024 10:35:46 +0100
Sample_Init:-------------------------------------------^
struct CmdClientData *cmdClientDataPtr;
cmdClientDataPtr = ckalloc(sizeof(struct Sha1ClientData));
Shouldn't this be "struct CmdClientDataPtr"?
Yes, good catch
cmdClientDataPtr->sha1CmdTolken = Tcl_CreateObjCommand(---------------^
interp, "sha1", (Tcl_ObjCmdProc *)Sha1_Cmd,
sha1ClientDataPtr, Sha1_CmdDeleteProc);
Shouldn't this be "cmdClientDataPtr"?
Well, I use a client data for the command "sha1ClientDataPtr" with the
command state, which is deleted by the command delete proc
"Sha1_CmdDeleteProc".
In addition, there is assoc data of the dll "cmdClientDataPtr" to keep
the command tokens for removal within the unload procedure.
Is this design sensible ?
Can't say without seeing the real code, but ...
* If you delete the command [sha1], either using [rename] or by deleting
the current interpreter or namespace, you might want to unload the
library as well, and free all allocated resources;
* If you [unload] the library, you might want to also delete the [sha1]
command, and free all allocated resources.
* If you are using Tcl_{Get|Set}AssocData, you have to check the right
time to use ckfree if both cleanup functions depends on clientdata
to be valid. In this case, Tcl_Preserve/Tcl_Release and
Tcl_EventuallyFree might be useful. Or maybe adding a flag in the
clientdata structure to mark "This cleanup function was already been called".
THanks for all,
Harald
Regards
On Tue, 10 Dec 2024 10:35:46 +0100
Harald Oehlmann <wortkarg3@yahoo.com> wrote:
You get (at least!) three "levels" for storing cliendata to Tcl:
* Per command, using the clientdata argument of Tcl_CreateObjCommand().
* Per interp, using Tcl_{Set|Get}AssocData().
* Per thread, using Tcl_GetThreadData().
Sysop: | DaiTengu |
---|---|
Location: | Appleton, WI |
Users: | 1,007 |
Nodes: | 10 (0 / 10) |
Uptime: | 60:54:02 |
Calls: | 13,152 |
Calls today: | 2 |
Files: | 186,574 |
D/L today: |
1,799 files (806M bytes) |
Messages: | 3,312,978 |