Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Can one "reload" a package?

567 views
Skip to first unread message

sbromle

unread,
Mar 7, 2006, 11:12:22 AM3/7/06
to
Hi folks,
Thanks in advance for any insight you could
give on this problem. I hope that this may be
of interest to others on the list as well.

I have an application which support plugins.
These plugins can be reloaded at any time
and their state is preserved in the "core" application.
This allows me to actively develop a plugin
and to test the results of any changes and compare
it to the previous version, without restarting
the main application.

So now I'm beginning to push the core application
beyond it's original intent,
and I figure the best way to do this is to give
it the power and scriptability that Tcl provides.
Ideally, I'd like to make each plugin a Tcl Package,
and then be able to ask for the core application
to reload a package if I modify it.

Looking at the "load" command doc, it looks like
unloading is impossible. Is anyone aware of an alternative
method that I can use to get this effect?

The way I do it in C is to have all the plugins dynamically
loadable shared libraries, which register themselves and the
commands they provide (a la Tcl Packages I guess.) But in C,
I can just close the library, deregister the commands, and reopen
the new one.

Any help, comments, and suggestions would be greatly appreciated!

Thanks,
Sam.

Georgios Petasis

unread,
Mar 7, 2006, 11:29:11 AM3/7/06
to
Tcl core offers the unload command, which can be used to
unload a C extension, previously loaded with load, IF the
C extension has been maded unloadable (i.e. have the proper
functions in place). However,
you have to use tcl 8.5. See http://wiki.tcl.tk/10852

George

"sbromle" <s...@sambromley.com> wrote in message
news:1141747942....@i40g2000cwc.googlegroups.com...

sbromle

unread,
Mar 7, 2006, 11:56:41 AM3/7/06
to
Hi Georgios,
Thank you for your reply. I've just read your TIP. This
is exactly what I am looking for. Unfortunately, I don't
see the adoption of Tcl8.5 as something we can take on
right now. My fear is that if we switch to 8.5, we may have
to expend resources on keeping up to date with a moving target.
(Though admittedly a very stable and feature-full target. :) )

I've downloaded the Tcl8.5 source in a hope to see how the
unloading facility is implemented, but it looks more invasive
that I anticipated. (Probably because I am not very familiar
with the organizational structure of the Tcl code base.)

I have an idea on how I could quickly emulate the effect, but
I'm not sure if this would work, so I would appreciate your input.

If I manually dynamically load the shared libraries on the C side
(thus I handle the "load" myself), and then, upon "unload", I :
1) rename all the registered commands to the empty string
2) save the state of the plugin (if any)
3) unload it (basically just close the library)
4) then reload it
5) register the commands, and
6) restore the state,
will the state of the main interpreter be ok?

I guess the question is, does the registering of a comand, followed by
the
renaming of that command to the empty string, return the interpretor to
the
same state as before the initial load?

Thanks!
Sam.

MartinLemburg@UGS

unread,
Mar 7, 2006, 11:59:06 AM3/7/06
to
Hi Sam,

if it would be a pure tcl package I would say, use ...

% package forget abc
% package require abc
1.0

But if it's about C(++) related shared libraries loaded into tcl, than
you must use tcl 8.5 to use the unload command.

The unload command asks for an unload function to execute this function
like the load command asks for an init function while loading the
shared library.

Due to the problem, that packages (loaded by "package require") have no
"forget" or "unload" callback, a package should provide a "unload"
procedure or command to unload itself.
After unloading it can be reloaded, hopefully!

But be careful while unloading to reload to clean up everything, that
may influence the reload in a non-wanted way!

Best regards,

Martin Lemburg
UGS - Tranforming the Process of Innovation

sbromle

unread,
Mar 7, 2006, 12:50:21 PM3/7/06
to
Hi Martin,
Thank you for your response.
You mention that I should be careful to clean up everything.
The things I can think of now are
1) Unset any commands that have been defined.
2) Remove any new Tcl object types that have been defined (is this
possible?)
3) Free any memory allocated/managed by the package/plugin.
4) Close the dlopen'ed library. (If I implement load/unload myself)
Do you feel that this an exaustive list?

Thanks for the help.
Sam.

Ralf Fassel

unread,
Mar 7, 2006, 1:50:36 PM3/7/06
to
* "sbromle" <s...@sambromley.com>

| This allows me to actively develop a plugin and to test the results
| of any changes and compare it to the previous version, without
| restarting the main application.
--<snip-snip>--

| Ideally, I'd like to make each plugin a Tcl Package,
| and then be able to ask for the core application
| to reload a package if I modify it.

If you can't/don't want to use the 8.5 'unload', I'd have the
init-code of the shared library create an TCL-unload-proc for that
library. Something in the line of

static int unload_foo(Clientdata interp...) {
// in interp:
// rename all commands to {}
// delete all variables created {}
// free all memory etc
// dlclose? dunno...
//
}
int Foo_Init(Tcl_Interp interp) {
...
Tcl_CreateObjCmd(cmd1,...);
...
Tcl_CreateObjCmd(unload-FOO, ..., (Clientdata) interp, unload_foo);
return TCL_OK;
}

Then if you 'load' the lib, Foo_Init() is called which creates the
unload proc. Later, you call the unload-proc, either from TCL or from
C et voila...

Haven't tried that myself...
R'

sbromle

unread,
Mar 7, 2006, 2:04:52 PM3/7/06
to
Hi Ralf,
This is basically how I'm doing it now with the C-only based
plugin reloading system. Thanks for adding your thoughts on it
as it gives me encouragement that I might be able to move forward
with it. If no one sees any obvious issues regarding leaving the
interpreter in a bad state, or w.r.t. any additional
side effects caused by loading a package that I need to account for,
then I will go ahead and give this a try. I'll report back to
the list with my findings

If anyone happens to think up any "watch out for"'s, please don't
hesitate to shout out. :)

Thanks for the input.
Best regards,
Sam.

Georgios Petasis

unread,
Mar 7, 2006, 2:25:00 PM3/7/06
to
Then, the only solution I see is to port the unload functionality
from 8.5 to 8.4. Do you use your own compiled distributions, or
ActiveTcl? In the latter case, I suppose you can make
a new C extension, which implements both load & unload...
It souldn't be difficult, as the implementation is aslready there...

George

"sbromle" <s...@sambromley.com> wrote in message

news:1141750601.4...@p10g2000cwp.googlegroups.com...

Adrian Ho

unread,
Mar 7, 2006, 8:35:38 PM3/7/06
to
On 2006-03-07, sbromle <s...@sambromley.com> wrote:
> 2) Remove any new Tcl object types that have been defined (is this
> possible?)

You want to use Tcl_DecrRefCount() for this, methinks.

- Adrian

Don Porter

unread,
Mar 7, 2006, 9:14:06 PM3/7/06
to
sbromle <s...@sambromley.com> wrote:
>> 2) Remove any new Tcl object types that have been defined (is this
>> possible?)

Adrian Ho wrote:
> You want to use Tcl_DecrRefCount() for this, methinks.

No, that's a completely different topic.

Once you register a Tcl_ObjType with Tcl_RegisterObjType(), you're
stuck. You won't be able to [unload] that extension.

The solution? Don't call Tcl_RegisterObjType().

There's no need to register your Tcl_ObjType in order to use it to
your heart's content within your extension, and the Tcl_ObjType need
not be registered in order to pass through the core.

It turns out that there are very few situations where registering the
Tcl_ObjType with the core has any value. Just don't do it, at least
not until experience has convinced you there's something you just can't
accomplish without doing so.

--
| Don Porter Mathematical and Computational Sciences Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|

sbromle

unread,
Mar 7, 2006, 10:11:31 PM3/7/06
to
Ok, thanks Don. This is an important point.
I've been looking at the "Blob" command in
"Practical Programming in Tcl and Tk (4th ed)",
and I think this approach will get me 90% there,
(w.r.t. handling my C structure data).
Thank you for clarifying the issue with new Tcl Object
types.
Sam.

Adrian Ho

unread,
Mar 7, 2006, 10:40:38 PM3/7/06
to
On 2006-03-08, Don Porter <d...@email.nist.gov> wrote:
> sbromle <s...@sambromley.com> wrote:
>>> 2) Remove any new Tcl object types that have been defined (is this
>>> possible?)
>
> Adrian Ho wrote:
>> You want to use Tcl_DecrRefCount() for this, methinks.
>
> No, that's a completely different topic.

Argh, you're right.

Note to self: Rub sleep from eyes + get caffeine jolt before posting...

- Adrian

Juan C. Gil

unread,
Mar 8, 2006, 12:26:31 PM3/8/06
to
Martin,

The [package forget] command does NOT unload a pure Tcl package, it
simply instructs the interpreter to forget about previously found
[package ifneeded] scripts for that package.

See The Simple Development Library
http://simpledevlib.sourceforge.net/
and, more specifically, the SimplePackage package
http://simpledevlib.sourceforge.net/SimplePackage.html
for more no this issue.

Juan Carlos---

0 new messages