Update of /cvsroot/fxruby/FXRuby/ext/fox
In directory usw-pr-cvs1:/tmp/cvs-serv11783/ext/fox
Modified Files:
Tag: release10
FXRuby.cpp
Log Message:
Further attempts to get GC correct.
Index: FXRuby.cpp
===================================================================
RCS file: /cvsroot/fxruby/FXRuby/ext/fox/FXRuby.cpp,v
retrieving revision 1.40.2.2
retrieving revision 1.40.2.3
diff -C2 -d -r1.40.2.2 -r1.40.2.3
*** FXRuby.cpp 8 May 2002 16:33:22 -0000 1.40.2.2
--- FXRuby.cpp 8 May 2002 22:37:46 -0000 1.40.2.3
***************
*** 74,81 ****
// Wrapper around SWIG_NewPointerObj()
VALUE FXRbNewPointerObj(void *ptr,swig_type_info* ty){
VALUE obj=SWIG_NewPointerObj(ptr,ty,1);
! FXRbRegisterRubyObj(obj,ptr);
return obj;
}
--- 74,100 ----
+ /**
+ * Maps C++ objects to Ruby instances.
+ * The objects in this map were created from Ruby code and are typically
+ * backed by one of our custom C++ classes (like FXRbButton). When the
+ * associated Ruby instance is garbage-collected this C++ object will be
+ * destroyed, so it's important that the objects in this map get marked
+ * during GC's mark phase if they're still reachable.
+ */
+ static std::map<const void*,VALUE> FXRuby_ObjMap;
+
+ /**
+ * Maps C++ objects to Ruby instances.
+ * The objects in this map were created by FOX and are backed by standard
+ * FOX classes (like FXButton). Unlike the objects stored in FXRuby_ObjMap
+ * (see above), when the associated Ruby instance is garbage-collected
+ * this C++ object will _not_ be destroyed.
+ */
+ static std::map<const void*,VALUE> FXRuby_BorrowedRefs;
+
// Wrapper around SWIG_NewPointerObj()
VALUE FXRbNewPointerObj(void *ptr,swig_type_info* ty){
VALUE obj=SWIG_NewPointerObj(ptr,ty,1);
! FXRuby_BorrowedRefs[ptr]=obj;
return obj;
}
***************
*** 88,94 ****
- // Maps C++ objects to Ruby instances
- static std::map<const void*,VALUE> FXRuby_ObjMap;
-
// Should we catch exceptions thrown by message handlers?
FXbool FXRbCatchExceptions=FALSE;
--- 107,110 ----
***************
*** 128,141 ****
FXASSERT(FXRuby_ObjMap.find(foxObj)==FXRuby_ObjMap.end());
}
}
/**
! * Return the Ruby instance associated with this C++ object (if any),
! * or Qnil if no associated Ruby instance was found.
*/
! VALUE FXRbGetRubyObj(const void *foxObj) {
std::map<const void*,VALUE>::const_iterator itr=FXRuby_ObjMap.find(foxObj);
! return (itr!=FXRuby_ObjMap.end()) ? itr->second : Qnil;
}
--- 144,174 ----
FXASSERT(FXRuby_ObjMap.find(foxObj)==FXRuby_ObjMap.end());
}
+
+ std::map<const void*,VALUE>::iterator itr2=FXRuby_BorrowedRefs.find(foxObj);
+ if(itr2!=FXRuby_BorrowedRefs.end()){
+ obj=itr2->second;
+ DATA_PTR(obj)=0;
+ FXRuby_BorrowedRefs.erase(itr2);
+ FXASSERT(FXRuby_BorrowedRefs.find(foxObj)==FXRuby_BorrowedRefs.end());
+ }
}
/**
! * Return the registered Ruby class instance associated with this
! * FOX object, or Qnil if not found.
*/
! VALUE FXRbGetRubyObj(const void *foxObj,FXbool searchBoth){
std::map<const void*,VALUE>::const_iterator itr=FXRuby_ObjMap.find(foxObj);
! if(itr!=FXRuby_ObjMap.end()){
! return itr->second;
! }
! else if(searchBoth){
! itr=FXRuby_BorrowedRefs.find(foxObj);
! return (itr!=FXRuby_BorrowedRefs.end()) ? itr->second : Qnil;
! }
! else{
! return Qnil;
! }
}
***************
*** 146,151 ****
*/
VALUE FXRbGetRubyObj(const void *foxObj, const char *type){
! VALUE rbObj = FXRbGetRubyObj(foxObj);
! return (rbObj == Qnil) ? FXRbNewPointerObj(const_cast<void*>(foxObj), FXRbTypeQuery(type)) : rbObj;
}
--- 179,184 ----
*/
VALUE FXRbGetRubyObj(const void *foxObj, const char *type){
! VALUE rbObj=FXRbGetRubyObj(foxObj,TRUE);
! return (rbObj==Qnil) ? FXRbNewPointerObj(const_cast<void*>(foxObj), FXRbTypeQuery(type)) : rbObj;
}
***************
*** 156,160 ****
void FXRbGcMark(void *obj){
if(obj){
! VALUE value=FXRbGetRubyObj(obj);
if(value!=Qnil){
#if RUBY_VERSION_CODE < 172
--- 189,193 ----
void FXRbGcMark(void *obj){
if(obj){
! VALUE value=FXRbGetRubyObj(obj); // only search FXRuby_ObjMap!
if(value!=Qnil){
#if RUBY_VERSION_CODE < 172
|