diff options
Diffstat (limited to 'python')
-rw-r--r-- | python/modules/IcePy/Operation.cpp | 2 | ||||
-rw-r--r-- | python/modules/IcePy/Types.cpp | 222 | ||||
-rw-r--r-- | python/modules/IcePy/Types.h | 26 | ||||
-rw-r--r-- | python/modules/IcePy/ValueFactoryManager.cpp | 2 | ||||
-rw-r--r-- | python/python/Ice/__init__.py | 2 |
5 files changed, 102 insertions, 152 deletions
diff --git a/python/modules/IcePy/Operation.cpp b/python/modules/IcePy/Operation.cpp index 169f554766a..bbbbff6399f 100644 --- a/python/modules/IcePy/Operation.cpp +++ b/python/modules/IcePy/Operation.cpp @@ -2185,7 +2185,7 @@ IcePy::Invocation::validateException(const OperationPtr& op, PyObject* ex) const { for(ExceptionInfoList::const_iterator p = op->exceptions.begin(); p != op->exceptions.end(); ++p) { - if(PyObject_IsInstance(ex, (*p)->pythonType.get())) + if(PyObject_IsInstance(ex, (*p)->pythonType)) { return true; } diff --git a/python/modules/IcePy/Types.cpp b/python/modules/IcePy/Types.cpp index 4c4eea9b778..3b7c1024918 100644 --- a/python/modules/IcePy/Types.cpp +++ b/python/modules/IcePy/Types.cpp @@ -48,14 +48,6 @@ static ExceptionInfoMap _exceptionInfoMap; namespace IcePy { -class InfoMapDestroyer -{ -public: - - ~InfoMapDestroyer(); -}; -static InfoMapDestroyer infoMapDestroyer; - struct TypeInfoObject { PyObject_HEAD @@ -149,6 +141,12 @@ extern "C" static void typeInfoDealloc(TypeInfoObject* self) { + // + // Every TypeInfo object is assigned to a "_t_XXX" variable in its enclosing module. Python releases these + // objects during shutdown, which gives us a chance to release resources and break cyclic references. + // + assert(self->info); + (*self->info)->destroy(); delete self->info; Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); } @@ -1060,8 +1058,6 @@ IcePy::EnumInfo::EnumInfo(const string& ident, PyObject* t, PyObject* e) : assert(PyType_Check(t)); assert(PyDict_Check(e)); - Py_INCREF(t); - Py_ssize_t pos = 0; PyObject* key; PyObject* value; @@ -1095,7 +1091,7 @@ IcePy::EnumInfo::getId() const bool IcePy::EnumInfo::validate(PyObject* val) { - return PyObject_IsInstance(val, pythonType.get()) == 1; + return PyObject_IsInstance(val, pythonType) == 1; } bool @@ -1167,10 +1163,16 @@ IcePy::EnumInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintObjec out << getString(p.get()); } +void +IcePy::EnumInfo::destroy() +{ + const_cast<EnumeratorMap&>(enumerators).clear(); +} + Ice::Int IcePy::EnumInfo::valueForEnumerator(PyObject* p) const { - assert(PyObject_IsInstance(p, pythonType.get()) == 1); + assert(PyObject_IsInstance(p, pythonType) == 1); PyObjectHandle v = PyObject_GetAttrString(p, STRCAST("_value")); if(!v.get()) @@ -1308,8 +1310,6 @@ IcePy::StructInfo::StructInfo(const string& ident, PyObject* t, PyObject* m) : assert(PyType_Check(t)); assert(PyTuple_Check(m)); - Py_INCREF(t); - DataMemberList opt; convertDataMembers(m, const_cast<DataMemberList&>(members), opt, false); assert(opt.empty()); @@ -1335,7 +1335,7 @@ IcePy::StructInfo::getId() const bool IcePy::StructInfo::validate(PyObject* val) { - return val == Py_None || PyObject_IsInstance(val, pythonType.get()) == 1; + return val == Py_None || PyObject_IsInstance(val, pythonType) == 1; } bool @@ -1374,14 +1374,14 @@ void IcePy::StructInfo::marshal(PyObject* p, Ice::OutputStream* os, ObjectMap* objectMap, bool optional, const Ice::StringSeq*) { - assert(p == Py_None || PyObject_IsInstance(p, pythonType.get()) == 1); // validate() should have caught this. + assert(p == Py_None || PyObject_IsInstance(p, pythonType) == 1); // validate() should have caught this. if(p == Py_None) { if(!_nullMarshalValue.get()) { PyObjectHandle args = PyTuple_New(0); - PyTypeObject* type = reinterpret_cast<PyTypeObject*>(pythonType.get()); + PyTypeObject* type = reinterpret_cast<PyTypeObject*>(pythonType); _nullMarshalValue = type->tp_new(type, args.get(), 0); type->tp_init(_nullMarshalValue.get(), args.get(), 0); // Initialize the struct members } @@ -1431,7 +1431,7 @@ void IcePy::StructInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& cb, PyObject* target, void* closure, bool optional, const Ice::StringSeq*) { - PyObjectHandle p = instantiate(pythonType.get()); + PyObjectHandle p = instantiate(pythonType); if(!p.get()) { assert(PyErr_Occurred()); @@ -1496,15 +1496,8 @@ IcePy::StructInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintObj void IcePy::StructInfo::destroy() { - for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p) - { - (*p)->type->destroy(); - } const_cast<DataMemberList&>(members).clear(); - if(_nullMarshalValue.get()) - { - _nullMarshalValue.release(); - } + _nullMarshalValue = 0; } PyObject* @@ -1774,11 +1767,7 @@ IcePy::SequenceInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintO void IcePy::SequenceInfo::destroy() { - if(elementType) - { - elementType->destroy(); - const_cast<TypeInfoPtr&>(elementType) = 0; - } + const_cast<TypeInfoPtr&>(elementType) = 0; } PyObject* @@ -2448,7 +2437,7 @@ IcePy::CustomInfo::getId() const bool IcePy::CustomInfo::validate(PyObject* val) { - return PyObject_IsInstance(val, pythonType.get()) == 1; + return PyObject_IsInstance(val, pythonType) == 1; } bool @@ -2479,7 +2468,7 @@ void IcePy::CustomInfo::marshal(PyObject* p, Ice::OutputStream* os, ObjectMap* objectMap, bool, const Ice::StringSeq* metaData) { - assert(PyObject_IsInstance(p, pythonType.get()) == 1); // validate() should have caught this. + assert(PyObject_IsInstance(p, pythonType) == 1); // validate() should have caught this. PyObjectHandle obj = PyObject_CallMethod(p, STRCAST("IsInitialized"), 0); if(!obj.get()) @@ -2530,7 +2519,7 @@ IcePy::CustomInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& c assert(PyErr_Occurred()); throw AbortMarshaling(); } - PyTypeObject* type = reinterpret_cast<PyTypeObject*>(pythonType.get()); + PyTypeObject* type = reinterpret_cast<PyTypeObject*>(pythonType); PyObjectHandle p = type->tp_new(type, args.get(), 0); if(!p.get()) { @@ -2593,11 +2582,6 @@ IcePy::CustomInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintObj } } -void -IcePy::CustomInfo::destroy() -{ -} - // // DictionaryInfo implementation. // @@ -2825,16 +2809,8 @@ IcePy::DictionaryInfo::KeyCallback::unmarshaled(PyObject* val, PyObject*, void*) void IcePy::DictionaryInfo::destroy() { - if(keyType) - { - keyType->destroy(); - keyType = 0; - } - if(valueType) - { - valueType->destroy(); - valueType = 0; - } + keyType = 0; + valueType = 0; } // @@ -2843,7 +2819,7 @@ IcePy::DictionaryInfo::destroy() IcePy::ClassInfo::ClassInfo(const string& ident) : id(ident), defined(false) { - const_cast<PyObjectHandle&>(typeObj) = createType(this); + typeObj = createType(this); } void @@ -2868,8 +2844,7 @@ IcePy::ClassInfo::define(PyObject* t, PyObject* b, PyObject* i) const_cast<ClassInfoList&>(interfaces).push_back(iface); } - const_cast<PyObjectHandle&>(pythonType) = t; - Py_INCREF(t); + pythonType = t; const_cast<bool&>(defined) = true; } @@ -2978,7 +2953,6 @@ IcePy::ClassInfo::destroy() { const_cast<ClassInfoPtr&>(base) = 0; const_cast<ClassInfoList&>(interfaces).clear(); - const_cast<PyObjectHandle&>(typeObj) = 0; // Break circular reference. } // @@ -2987,7 +2961,7 @@ IcePy::ClassInfo::destroy() IcePy::ValueInfo::ValueInfo(const string& ident) : id(ident), compactId(-1), preserve(false), interface(false), defined(false) { - const_cast<PyObjectHandle&>(typeObj) = createType(this); + typeObj = createType(this); } void @@ -3008,8 +2982,7 @@ IcePy::ValueInfo::define(PyObject* t, int compact, bool pres, bool intf, PyObjec convertDataMembers(m, const_cast<DataMemberList&>(members), const_cast<DataMemberList&>(optionalMembers), true); - const_cast<PyObjectHandle&>(pythonType) = t; - Py_INCREF(t); + pythonType = t; const_cast<bool&>(defined) = true; } @@ -3023,7 +2996,7 @@ IcePy::ValueInfo::getId() const bool IcePy::ValueInfo::validate(PyObject* val) { - return val == Py_None || PyObject_IsInstance(val, pythonType.get()) == 1; + return val == Py_None || PyObject_IsInstance(val, pythonType) == 1; } bool @@ -3054,7 +3027,7 @@ void IcePy::ValueInfo::marshal(PyObject* p, Ice::OutputStream* os, ObjectMap* objectMap, bool, const Ice::StringSeq*) { - if(!pythonType.get()) + if(!pythonType) { PyErr_Format(PyExc_RuntimeError, STRCAST("class %s is declared but not defined"), id.c_str()); throw AbortMarshaling(); @@ -3067,7 +3040,7 @@ IcePy::ValueInfo::marshal(PyObject* p, Ice::OutputStream* os, ObjectMap* objectM return; } - if(!PyObject_IsInstance(p, pythonType.get())) + if(!PyObject_IsInstance(p, pythonType)) { PyErr_Format(PyExc_ValueError, STRCAST("expected value of type %s"), id.c_str()); throw AbortMarshaling(); @@ -3115,7 +3088,7 @@ void IcePy::ValueInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& cb, PyObject* target, void* closure, bool, const Ice::StringSeq*) { - if(!pythonType.get()) + if(!pythonType) { PyErr_Format(PyExc_RuntimeError, STRCAST("class %s is declared but not defined"), id.c_str()); throw AbortMarshaling(); @@ -3185,16 +3158,7 @@ void IcePy::ValueInfo::destroy() { const_cast<ValueInfoPtr&>(base) = 0; - if(!members.empty()) - { - DataMemberList ml = members; - const_cast<DataMemberList&>(members).clear(); - for(DataMemberList::iterator p = ml.begin(); p != ml.end(); ++p) - { - (*p)->type->destroy(); - } - } - const_cast<PyObjectHandle&>(typeObj) = 0; // Break circular reference. + const_cast<DataMemberList&>(members).clear(); } void @@ -3248,14 +3212,13 @@ IcePy::ValueInfo::printMembers(PyObject* value, IceUtilInternal::Output& out, Pr IcePy::ProxyInfo::ProxyInfo(const string& ident) : id(ident) { - const_cast<PyObjectHandle&>(typeObj) = createType(this); + typeObj = createType(this); // Borrowed reference. } void IcePy::ProxyInfo::define(PyObject* t) { - const_cast<PyObjectHandle&>(pythonType) = t; - Py_INCREF(t); + pythonType = t; // Borrowed reference. } string @@ -3267,7 +3230,7 @@ IcePy::ProxyInfo::getId() const bool IcePy::ProxyInfo::validate(PyObject* val) { - return val == Py_None || PyObject_IsInstance(val, pythonType.get()) == 1; + return val == Py_None || PyObject_IsInstance(val, pythonType) == 1; } bool @@ -3334,13 +3297,13 @@ IcePy::ProxyInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& cb return; } - if(!pythonType.get()) + if(!pythonType) { PyErr_Format(PyExc_RuntimeError, STRCAST("class %s is declared but not defined"), id.c_str()); throw AbortMarshaling(); } - PyObjectHandle p = createProxy(proxy, proxy->ice_getCommunicator(), pythonType.get()); + PyObjectHandle p = createProxy(proxy, proxy->ice_getCommunicator(), pythonType); cb->unmarshaled(p.get(), target, closure); } @@ -3369,12 +3332,6 @@ IcePy::ProxyInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintObje } } -void -IcePy::ProxyInfo::destroy() -{ - const_cast<PyObjectHandle&>(typeObj) = 0; // Break circular reference. -} - // // ObjectWriter implementation. // @@ -3636,33 +3593,6 @@ IcePy::ObjectReader::getSlicedData() const } // -// InfoMapDestroyer implementation. -// -IcePy::InfoMapDestroyer::~InfoMapDestroyer() -{ - { - for(ProxyInfoMap::iterator p = _proxyInfoMap.begin(); p != _proxyInfoMap.end(); ++p) - { - p->second->destroy(); - } - } - { - for(ClassInfoMap::iterator p = _classInfoMap.begin(); p != _classInfoMap.end(); ++p) - { - p->second->destroy(); - } - } - { - for(ValueInfoMap::iterator p = _valueInfoMap.begin(); p != _valueInfoMap.end(); ++p) - { - p->second->destroy(); - } - } - _compactIdMap.clear(); - _exceptionInfoMap.clear(); -} - -// // ReadObjectCallback implementation. // IcePy::ReadObjectCallback::ReadObjectCallback(const ValueInfoPtr& info, const UnmarshalCallbackPtr& cb, @@ -3689,7 +3619,7 @@ IcePy::ReadObjectCallback::invoke(const Ice::ObjectPtr& p) // Verify that the object's type is compatible with the formal type. // PyObject* obj = reader->getObject(); // Borrowed reference. - if(!PyObject_IsInstance(obj, _info->pythonType.get())) + if(!PyObject_IsInstance(obj, _info->pythonType)) { Ice::UnexpectedObjectException ex(__FILE__, __LINE__); ex.reason = "unmarshaled object is not an instance of " + _info->id; @@ -3712,7 +3642,7 @@ IcePy::ReadObjectCallback::invoke(const Ice::ObjectPtr& p) void IcePy::ExceptionInfo::marshal(PyObject* p, Ice::OutputStream* os, ObjectMap* objectMap) { - if(!PyObject_IsInstance(p, pythonType.get())) + if(!PyObject_IsInstance(p, pythonType)) { PyErr_Format(PyExc_ValueError, STRCAST("expected exception %s"), id.c_str()); throw AbortMarshaling(); @@ -3791,7 +3721,7 @@ IcePy::ExceptionInfo::writeMembers(PyObject* p, Ice::OutputStream* os, const Dat PyObject* IcePy::ExceptionInfo::unmarshal(Ice::InputStream* is) { - PyObjectHandle p = createExceptionInstance(pythonType.get()); + PyObjectHandle p = createExceptionInstance(pythonType); ExceptionInfoPtr info = this; while(info) @@ -3834,7 +3764,7 @@ IcePy::ExceptionInfo::unmarshal(Ice::InputStream* is) void IcePy::ExceptionInfo::print(PyObject* value, IceUtilInternal::Output& out) { - if(!PyObject_IsInstance(value, pythonType.get())) + if(!PyObject_IsInstance(value, pythonType)) { out << "<invalid value - expected " << id << ">"; return; @@ -4504,10 +4434,13 @@ IcePy_declareProxy(PyObject*, PyObject* args) { info = new ProxyInfo(proxyId); addProxyInfo(proxyId, info); + return info->typeObj; // Delegate ownership to the global "_t_XXX" variable. + } + else + { + Py_INCREF(info->typeObj); + return info->typeObj; } - - Py_INCREF(info->typeObj.get()); - return info->typeObj.get(); } extern "C" @@ -4531,12 +4464,15 @@ IcePy_defineProxy(PyObject*, PyObject* args) { info = new ProxyInfo(proxyId); addProxyInfo(proxyId, info); + info->define(type); + return info->typeObj; // Delegate ownership to the global "_t_XXX" variable. + } + else + { + info->define(type); + Py_INCREF(info->typeObj); + return info->typeObj; } - - info->define(type); - - Py_INCREF(info->typeObj.get()); - return info->typeObj.get(); } extern "C" @@ -4554,10 +4490,13 @@ IcePy_declareClass(PyObject*, PyObject* args) { info = new ClassInfo(id); addClassInfo(id, info); + return info->typeObj; // Delegate ownership to the global "_t_XXX" variable. + } + else + { + Py_INCREF(info->typeObj); + return info->typeObj; } - - Py_INCREF(info->typeObj.get()); - return info->typeObj.get(); } extern "C" @@ -4586,12 +4525,15 @@ IcePy_defineClass(PyObject*, PyObject* args) { info = new ClassInfo(id); addClassInfo(id, info); + info->define(type, base, interfaces); + return info->typeObj; // Delegate ownership to the global "_t_XXX" variable. + } + else + { + info->define(type, base, interfaces); + Py_INCREF(info->typeObj); + return info->typeObj; } - - info->define(type, base, interfaces); - - Py_INCREF(info->typeObj.get()); - return info->typeObj.get(); } extern "C" @@ -4609,10 +4551,13 @@ IcePy_declareValue(PyObject*, PyObject* args) { info = new ValueInfo(id); addValueInfo(id, info); + return info->typeObj; // Delegate ownership to the global "_t_XXX" variable. + } + else + { + Py_INCREF(info->typeObj); + return info->typeObj; } - - Py_INCREF(info->typeObj.get()); - return info->typeObj.get(); } extern "C" @@ -4635,6 +4580,8 @@ IcePy_defineValue(PyObject*, PyObject* args) assert(PyTuple_Check(meta)); + PyObject* r; + // // A ClassInfo object will already exist for this id if a forward declaration // was encountered, or if the Slice definition is being reloaded. In the latter @@ -4645,6 +4592,12 @@ IcePy_defineValue(PyObject*, PyObject* args) { info = new ValueInfo(id); addValueInfo(id, info); + r = info->typeObj; // Delegate ownership to the global "_t_XXX" variable. + } + else + { + Py_INCREF(info->typeObj); + r = info->typeObj; } info->define(type, compactId, preserve ? true : false, interface ? true : false, base, members); @@ -4658,8 +4611,8 @@ IcePy_defineValue(PyObject*, PyObject* args) } _compactIdMap.insert(CompactIdMap::value_type(info->compactId, info)); } - Py_INCREF(info->typeObj.get()); - return info->typeObj.get(); + + return r; } extern "C" @@ -4708,7 +4661,6 @@ IcePy_defineException(PyObject*, PyObject* args) } info->pythonType = type; - Py_INCREF(type); addExceptionInfo(id, info); diff --git a/python/modules/IcePy/Types.h b/python/modules/IcePy/Types.h index 5ca3d2296dc..b4409b7de40 100644 --- a/python/modules/IcePy/Types.h +++ b/python/modules/IcePy/Types.h @@ -236,11 +236,13 @@ public: virtual void print(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*); + virtual void destroy(); + Ice::Int valueForEnumerator(PyObject*) const; PyObject* enumeratorForValue(Ice::Int) const; const std::string id; - const PyObjectHandle pythonType; + PyObject* pythonType; // Borrowed reference - the enclosing Python module owns the reference. const Ice::Int maxValue; const EnumeratorMap enumerators; }; @@ -292,7 +294,7 @@ public: const std::string id; const DataMemberList members; - const PyObjectHandle pythonType; + PyObject* pythonType; // Borrowed reference - the enclosing Python module owns the reference. private: @@ -387,10 +389,8 @@ public: virtual void print(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*); - virtual void destroy(); - const std::string id; - const PyObjectHandle pythonType; + PyObject* pythonType; // Borrowed reference - the enclosing Python module owns the reference. }; typedef IceUtil::Handle<CustomInfo> CustomInfoPtr; @@ -474,8 +474,8 @@ public: const std::string id; const ClassInfoPtr base; const ClassInfoList interfaces; - const PyObjectHandle pythonType; - const PyObjectHandle typeObj; + PyObject* pythonType; // Borrowed reference - the enclosing Python module owns the reference. + PyObject* typeObj; // Borrowed reference - the "_t_XXX" variable owns the reference. const bool defined; }; @@ -518,8 +518,8 @@ public: const ValueInfoPtr base; const DataMemberList members; const DataMemberList optionalMembers; - const PyObjectHandle pythonType; - const PyObjectHandle typeObj; + PyObject* pythonType; // Borrowed reference - the enclosing Python module owns the reference. + PyObject* typeObj; // Borrowed reference - the "_t_XXX" variable owns the reference. const bool defined; }; @@ -548,11 +548,9 @@ public: virtual void print(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*); - virtual void destroy(); - const std::string id; - const PyObjectHandle pythonType; - const PyObjectHandle typeObj; + PyObject* pythonType; // Borrowed reference - the enclosing Python module owns the reference. + PyObject* typeObj; // Borrowed reference - the "_t_XXX" variable owns the reference. }; typedef IceUtil::Handle<ProxyInfo> ProxyInfoPtr; @@ -575,7 +573,7 @@ public: DataMemberList members; DataMemberList optionalMembers; bool usesClasses; - PyObjectHandle pythonType; + PyObject* pythonType; // Borrowed reference - the enclosing Python module owns the reference. private: diff --git a/python/modules/IcePy/ValueFactoryManager.cpp b/python/modules/IcePy/ValueFactoryManager.cpp index ca7b6c5779b..eaa8d9716c5 100644 --- a/python/modules/IcePy/ValueFactoryManager.cpp +++ b/python/modules/IcePy/ValueFactoryManager.cpp @@ -299,7 +299,7 @@ IcePy::DefaultValueFactory::create(const string& id) // // Instantiate the object. // - PyTypeObject* type = reinterpret_cast<PyTypeObject*>(info->pythonType.get()); + PyTypeObject* type = reinterpret_cast<PyTypeObject*>(info->pythonType); PyObjectHandle args = PyTuple_New(0); PyObjectHandle obj = type->tp_new(type, args.get(), 0); if(!obj.get()) diff --git a/python/python/Ice/__init__.py b/python/python/Ice/__init__.py index 73212f1e2bb..63b4cffebb7 100644 --- a/python/python/Ice/__init__.py +++ b/python/python/Ice/__init__.py @@ -737,7 +737,7 @@ FormatType.SlicedFormat = FormatType(2) IcePy._t_Object = IcePy.declareClass('::Ice::Object') IcePy._t_Value = IcePy.declareValue('::Ice::Object') IcePy._t_ObjectPrx = IcePy.declareProxy('::Ice::Object') -IcePy._t_LocalObject = IcePy.declareClass('::Ice::LocalObject') +IcePy._t_LocalObject = IcePy.declareValue('::Ice::LocalObject') # # Sequence mappings. |