From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7950 invoked from network); 10 Dec 1998 23:42:10 -0000 Received: from ns2.primenet.com.au (HELO primenet.com.au) (7795@203.24.36.3) by ns1.primenet.com.au with SMTP; 10 Dec 1998 23:42:10 -0000 Received: (qmail 11851 invoked from network); 10 Dec 1998 10:36:06 -0000 Received: from math.gatech.edu (list@130.207.146.50) by ns2.primenet.com.au with SMTP; 10 Dec 1998 10:36:06 -0000 Received: (from list@localhost) by math.gatech.edu (8.9.1/8.9.1) id FAA19390; Thu, 10 Dec 1998 05:30:28 -0500 (EST) Resent-Date: Thu, 10 Dec 1998 05:30:28 -0500 (EST) Date: Thu, 10 Dec 1998 11:28:46 +0100 (MET) Message-Id: <199812101028.LAA04331@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@math.gatech.edu In-reply-to: Peter Stephenson's message of Thu, 10 Dec 1998 10:22:17 +0100 Subject: Re: PATCH: wrapper functions in modules Resent-Message-ID: <"fCTyR3.0.sk4.4BwRs"@math> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/4742 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu 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@informatik.hu-berlin.de