Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: PATCH: wrapper functions in modules
- X-seq: zsh-workers 4742
- From: Sven Wischnowsky <wischnow@xxxxxxxxxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxxxxxxx
- Subject: Re: PATCH: wrapper functions in modules
- Date: Thu, 10 Dec 1998 11:28:46 +0100 (MET)
- In-reply-to: Peter Stephenson's message of Thu, 10 Dec 1998 10:22:17 +0100
Peter Stephenson wrote:
>
> Sven Wischnowsky wrote:
> > Alternatively I could change the code so that a module cannot be
> > unloaded if it has defined `after'-functions and there are currently
> > shell functions being executed.
>
> Would it be possible for zmodload in such circumstances to mark the
> function for unloading after the wrapper has been called, and then do
> so?
Yes, I like this idea. The patch below ensures that the real unloading
of a module happens only if there are no more `after'-functions to be
called.
Bye
Sven
diff -c os/exec.c Src/exec.c
*** os/exec.c Thu Dec 10 09:04:21 1998
--- Src/exec.c Thu Dec 10 11:22:29 1998
***************
*** 2661,2667 ****
void *xexitfn, *newexitfn;
char saveopts[OPT_SIZE];
int obreaks = breaks;
! FuncWrap wrap;
HEAPALLOC {
pushheap();
--- 2661,2667 ----
void *xexitfn, *newexitfn;
char saveopts[OPT_SIZE];
int obreaks = breaks;
! FuncWrap wrap, nwrap;
HEAPALLOC {
pushheap();
***************
*** 2709,2714 ****
--- 2709,2718 ----
for (wrap = wrappers; wrap; wrap = wrap->next) {
if (wrap->before)
wrap->before(wrap, name);
+ if (wrap->after) {
+ wrap->module->flags |= MOD_WRAPPER;
+ wrap->count++;
+ }
}
startparamscope();
ou = underscore;
***************
*** 2717,2725 ****
zsfree(underscore);
underscore = ou;
endparamscope();
! for (wrap = wrappers; wrap; wrap = wrap->next) {
! if (wrap->after)
wrap->after(wrap, name, lastval);
}
if (retflag) {
retflag = 0;
--- 2721,2739 ----
zsfree(underscore);
underscore = ou;
endparamscope();
! for (wrap = wrappers; wrap; wrap = nwrap) {
! nwrap = wrap->next;
! if (wrap->after) {
wrap->after(wrap, name, lastval);
+ wrap->count--;
+ if (!wrap->count) {
+ wrap->module->flags &= ~MOD_WRAPPER;
+ if (wrap->module->flags & MOD_UNLOAD) {
+ wrap->module->flags &= ~MOD_UNLOAD;
+ unload_module(wrap->module, NULL);
+ }
+ }
+ }
}
if (retflag) {
retflag = 0;
diff -c os/module.c Src/module.c
*** os/module.c Thu Dec 10 09:04:25 1998
--- Src/module.c Thu Dec 10 11:07:55 1998
***************
*** 326,338 ****
/**/
int
! addwrapper(FuncWrap w)
{
if (w->flags & WRAPF_ADDED)
return 1;
w->next = wrappers;
wrappers = w;
w->flags |= WRAPF_ADDED;
return 0;
}
--- 326,340 ----
/**/
int
! addwrapper(Module m, FuncWrap w)
{
if (w->flags & WRAPF_ADDED)
return 1;
w->next = wrappers;
wrappers = w;
w->flags |= WRAPF_ADDED;
+ w->module = m;
+ w->count = 0;
return 0;
}
***************
*** 342,348 ****
/**/
int
! deletewrapper(FuncWrap w)
{
FuncWrap p, q;
--- 344,350 ----
/**/
int
! deletewrapper(Module m, FuncWrap w)
{
FuncWrap p, q;
***************
*** 838,843 ****
--- 840,871 ----
}
/**/
+ int
+ unload_module(Module m, LinkNode node)
+ {
+ if (m->handle && cleanup_module(m))
+ return 1;
+ else {
+ if (m->handle)
+ dlclose(m->handle);
+ m->handle = NULL;
+ if(!m->deps) {
+ if (!node) {
+ for (node = firstnode(modules); node; incnode(node))
+ if (m == (Module) getdata(node))
+ break;
+ if (!node)
+ return 1;
+ }
+ remnode(modules, node);
+ zsfree(m->nam);
+ zfree(m, sizeof(*m));
+ }
+ }
+ return 0;
+ }
+
+ /**/
static int
bin_zmodload_load(char *nam, char **args, char *ops)
{
***************
*** 861,880 ****
goto cont;
}
}
-
m = (Module) getdata(node);
! if (m->handle && cleanup_module(m))
! ret = 1;
! else {
! if (m->handle)
! dlclose(m->handle);
! m->handle = NULL;
! if(!m->deps) {
! remnode(modules, node);
! zsfree(m->nam);
! zfree(m, sizeof(*m));
! }
}
} else if (!ops['i']) {
zwarnnam(nam, "no such module %s", *args, 0);
ret = 1;
--- 889,901 ----
goto cont;
}
}
m = (Module) getdata(node);
! if (!(m->flags & MOD_WRAPPER)) {
! if (unload_module(m, node))
! ret = 1;
}
+ else
+ m->flags |= MOD_UNLOAD;
} else if (!ops['i']) {
zwarnnam(nam, "no such module %s", *args, 0);
ret = 1;
diff -c os/zsh.h Src/zsh.h
*** os/zsh.h Thu Dec 10 09:04:27 1998
--- Src/zsh.h Thu Dec 10 10:49:44 1998
***************
*** 782,792 ****
int flags;
WrapBefore before;
WrapAfter after;
};
#define WRAPF_ADDED 1
! #define WRAPDEF(before, after) { NULL, 0, before, after }
/* node in builtin command hash table (builtintab) */
--- 782,795 ----
int flags;
WrapBefore before;
WrapAfter after;
+ Module module;
+ int count;
};
#define WRAPF_ADDED 1
! #define WRAPDEF(before, after) \
! { NULL, 0, before, after, NULL, 0 }
/* node in builtin command hash table (builtintab) */
***************
*** 838,843 ****
--- 841,848 ----
};
#define MOD_BUSY (1<<0)
+ #define MOD_WRAPPER (1<<1)
+ #define MOD_UNLOAD (1<<2)
/* node used in parameter hash table (paramtab) */
--
Sven Wischnowsky wischnow@xxxxxxxxxxxxxxxxxxxxxxx
Messages sorted by:
Reverse Date,
Date,
Thread,
Author