Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: PATCH: wrapper functions in modules



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