Hello Group, I could use an advice on how SEXP handles work. My aim is to implement a system where I initially set a few global variables that are used for communication between C and R code. Then I do some work with R code and periodically call a function of my own that will update the system state. Such a design is useful for many purposes (for GUIs to name one). I am not entirely sure that R can handle such a design but at the moment I cannot see any reasons why it could not. The problem I have is that the initially set global variables are not stable. Everything works for a while but eventually the system gets confused. It seems that the SEXP references to the state variables and to the callback functions may get altered and become pointing to some other variables. This will then rightfully give me the error messages like "attempt to apply non-function". My (maybe uneducated) guess is that this might have something to do with R memory management. The variables are connected to the namespace so a do not think they are removed. Maybe they are moved is such a way that my SEXP references are not able to follow. As you can see I am on thin ice here so please feel welcome to step in... My librtary contains ~20k lines of C code so I would not consider a bug here out of the question. I have tried to look for one but until now without success. My question is: can you see a design flaw here or is everything done according to R requirements and hence it is likely that there is a bug in my own code? One dirty correction I can see but have not tried is to use object names and findVar but this would make it less flexible (at least IMHO). I have quickly browsed the forums and the documentation I was able to find but found no answers. My system is FC3 with R version >= 2. There are two snippets of code that hopefully make clear what I am trying to achieve. The code is provided for illustration purposes only and I did not try to compile it. Best regards, Markku Mielityinen # C CODE ##################################################################### SEXP myrho = R_GlobalEnv; SEXP myvariable = R_NilValue; SEXP myfunction = R_NilValue; SEXP myinit(SEXP var, SEXP func) { myvariable = var; myfunction = func; return R_NilValue; } SEXP myexec(/* probably has some parameters that are omitted in this example */) { int state; SEXP thecall; /* do some work, then set the state and call a callback function if necessary */ PROTECT(myvariable); INTEGER(myvariable)[0] = state; UNPROTECT(1); if(state) { PROTECT(thecall = LCONS(myfunction, LCONS(myvariable, R_NilValue))); eval(thecall, myrho); UNPROTECT(1); } return R_NilValue; } ######################################################################## ######## # R CODE ##################################################################### myinit<-function(var,func) .Call("myinit",var,func) myexec<-function() .Call("myexec") state<-as.integer(1) callback<-function(state) { cat(sprintf("You got state %s\n",state)) } myinit() # do some work here and call myexec() periodically... ######################################################################## ########
Hi Markku. You have correctly diagnosed the problem that the initially set global variables "are not stable". In your call to myinit, you store a C-level reference to the var and func R objects. But you need to tell R's memory management that you need to hold onto them. Otherwise it is entitled to garbage collect them as it feels fit. In the C-code for myinit, you might add calls R_PreserveObject(myfunction) R_PreserveObject(myvariable) that is defined in Rinternals.h. These go after you assign values to your global variables. You are PROTECT()'ing these variables only in the call to myexec. D. Markku Mielityinen wrote:> Hello Group, > > I could use an advice on how SEXP handles work. My aim is to implement a > system where I initially set a few global variables that are used for > communication between C and R code. Then I do some work with R code and > periodically call a function of my own that will update the system > state. Such a design is useful for many purposes (for GUIs to name one). > I am not entirely sure that R can handle such a design but at the moment > I cannot see any reasons why it could not. The problem I have is that > the initially set global variables are not stable. Everything works for > a while but eventually the system gets confused. It seems that the SEXP > references to the state variables and to the callback functions may get > altered and become pointing to some other variables. This will then > rightfully give me the error messages like "attempt to apply > non-function". My (maybe uneducated) guess is that this might have > something to do with R memory management. The variables are connected to > the namespace so a do not think they are removed. Maybe they are moved > is such a way that my SEXP references are not able to follow. As you can > see I am on thin ice here so please feel welcome to step in... > > My librtary contains ~20k lines of C code so I would not consider a bug > here out of the question. I have tried to look for one but until now > without success. > > My question is: can you see a design flaw here or is everything done > according to R requirements and hence it is likely that there is a bug > in my own code? > > One dirty correction I can see but have not tried is to use object names > and findVar but this would make it less flexible (at least IMHO). > > I have quickly browsed the forums and the documentation I was able to > find but found no answers. > > My system is FC3 with R version >= 2. > > There are two snippets of code that hopefully make clear what I am > trying to achieve. The code is provided for illustration purposes only > and I did not try to compile it. > > Best regards, > Markku Mielityinen > > > # C CODE > ##################################################################### > > SEXP myrho = R_GlobalEnv; > SEXP myvariable = R_NilValue; > SEXP myfunction = R_NilValue; > > SEXP myinit(SEXP var, SEXP func) { > myvariable = var; > myfunction = func; > return R_NilValue; > } > > SEXP myexec(/* probably has some parameters that are omitted in this > example */) { > int state; > SEXP thecall; > > /* do some work, then set the state and call a callback function > if necessary */ > > PROTECT(myvariable); > INTEGER(myvariable)[0] = state; > UNPROTECT(1); > if(state) { > PROTECT(thecall = LCONS(myfunction, LCONS(myvariable, > R_NilValue))); > eval(thecall, myrho); > UNPROTECT(1); > } > > return R_NilValue; > } > > ######################################################################## > ######## > > # R CODE > ##################################################################### > > myinit<-function(var,func) .Call("myinit",var,func) > myexec<-function() .Call("myexec") > > state<-as.integer(1) > callback<-function(state) { cat(sprintf("You got state %s\n",state)) } > > myinit() > # do some work here and call myexec() periodically... > > ######################################################################## > ######## > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel-- Duncan Temple Lang duncan at wald.ucdavis.edu Department of Statistics work: (530) 752-4782 371 Kerr Hall fax: (530) 752-7099 One Shields Ave. University of California at Davis Davis, CA 95616, USA -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : https://stat.ethz.ch/pipermail/r-devel/attachments/20050817/35eda213/attachment.bin
R never moves objects in memory, but it may garbage collect them. What is not clear to me is that you can guarantee that the objects you pass in are not copies subject to garbage collection, but then I don't know how you are calling your functions. A way to make sure that your pointers remain valid is to PROTECT them etc on assignment. Using gctorture(TRUE) will probably ensure things break very quickly if gc-ing is the problem. On Wed, 17 Aug 2005, Markku Mielityinen wrote:> Hello Group, > > I could use an advice on how SEXP handles work. My aim is to implement a > system where I initially set a few global variables that are used for > communication between C and R code. Then I do some work with R code and > periodically call a function of my own that will update the system > state. Such a design is useful for many purposes (for GUIs to name one). > I am not entirely sure that R can handle such a design but at the moment > I cannot see any reasons why it could not. The problem I have is that > the initially set global variables are not stable. Everything works for > a while but eventually the system gets confused. It seems that the SEXP > references to the state variables and to the callback functions may get > altered and become pointing to some other variables. This will then > rightfully give me the error messages like "attempt to apply > non-function". My (maybe uneducated) guess is that this might have > something to do with R memory management. The variables are connected to > the namespace so a do not think they are removed. Maybe they are moved > is such a way that my SEXP references are not able to follow. As you can > see I am on thin ice here so please feel welcome to step in... > > My librtary contains ~20k lines of C code so I would not consider a bug > here out of the question. I have tried to look for one but until now > without success. > > My question is: can you see a design flaw here or is everything done > according to R requirements and hence it is likely that there is a bug > in my own code? > > One dirty correction I can see but have not tried is to use object names > and findVar but this would make it less flexible (at least IMHO). > > I have quickly browsed the forums and the documentation I was able to > find but found no answers. > > My system is FC3 with R version >= 2. > > There are two snippets of code that hopefully make clear what I am > trying to achieve. The code is provided for illustration purposes only > and I did not try to compile it. > > Best regards, > Markku Mielityinen > > > # C CODE > ##################################################################### > > SEXP myrho = R_GlobalEnv; > SEXP myvariable = R_NilValue; > SEXP myfunction = R_NilValue; > > SEXP myinit(SEXP var, SEXP func) { > myvariable = var; > myfunction = func; > return R_NilValue; > } > > SEXP myexec(/* probably has some parameters that are omitted in this > example */) { > int state; > SEXP thecall; > > /* do some work, then set the state and call a callback function > if necessary */ > > PROTECT(myvariable); > INTEGER(myvariable)[0] = state; > UNPROTECT(1); > if(state) { > PROTECT(thecall = LCONS(myfunction, LCONS(myvariable, > R_NilValue))); > eval(thecall, myrho); > UNPROTECT(1); > } > > return R_NilValue; > } > > ######################################################################## > ######## > > # R CODE > ##################################################################### > > myinit<-function(var,func) .Call("myinit",var,func) > myexec<-function() .Call("myexec") > > state<-as.integer(1) > callback<-function(state) { cat(sprintf("You got state %s\n",state)) } > > myinit() > # do some work here and call myexec() periodically... > > ######################################################################## > ######## > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > >-- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
Possibly Parallel Threads
- Robust multivariate regression with rlm
- Building new graphic device drivers with g++
- Strange t-test error: "grouping factor must have exactly 2 levels" while it does...
- legend of maps generated by function symbols
- Help with reading information of "summary"-Object