Browse Source

[2853] Make code safer by using RAII container

Also check for SEGMENT_UNUSED directly and return None for the segment
type in that case.
Mukund Sivaraman 12 years ago
parent
commit
3a874c84ba
1 changed files with 17 additions and 27 deletions
  1. 17 27
      src/lib/python/isc/datasrc/configurableclientlist_python.cc

+ 17 - 27
src/lib/python/isc/datasrc/configurableclientlist_python.cc

@@ -204,39 +204,29 @@ ConfigurableClientList_getStatus(PyObject* po_self, PyObject*) {
     try {
         const std::vector<DataSourceStatus> status = self->cppobj->getStatus();
 
-        PyObject* slist = PyList_New(status.size());
-        if (!slist) {
-            return (NULL);
-        }
+        PyObjectContainer slist(PyList_New(status.size()));
 
         for (size_t i = 0; i < status.size(); ++i) {
-            PyObject* segment_type = NULL;
-            try {
-                segment_type = Py_BuildValue(
-                    "s", status[i].getSegmentType().c_str());
-            } catch (const isc::InvalidOperation&) {
-                Py_INCREF(Py_None);
-                segment_type = Py_None;
-            }
+            PyObjectContainer segment_type;
 
-            // Py_BuildValue() is a C function and will not throw.
-            PyObject* tup = Py_BuildValue("(sOI)",
-                                          status[i].getName().c_str(),
-                                          segment_type,
-                                          status[i].getSegmentState());
-            if (segment_type) {
-                // The Py_BuildValue() above increments its refcount,
-                // so we drop our reference.
-                Py_DECREF(segment_type);
-            }
-            if (!tup) {
-                Py_DECREF(slist);
-                return (NULL);
+            if (status[i].getSegmentState() != SEGMENT_UNUSED) {
+                segment_type.reset(Py_BuildValue(
+                    "s", status[i].getSegmentType().c_str()));
+            } else {
+                 Py_INCREF(Py_None);
+                segment_type.reset(Py_None);
             }
-            PyList_SET_ITEM(slist, i, tup);
+
+            PyObjectContainer tup(Py_BuildValue("(sOI)",
+                                                status[i].getName().c_str(),
+                                                segment_type.get(),
+                                                status[i].getSegmentState()));
+            // The following "steals" our reference on tup, so we must
+            // not decref.
+            PyList_SET_ITEM(slist.get(), i, tup.release());
         }
 
-        return (slist);
+        return (slist.release());
     } catch (const std::exception& exc) {
         PyErr_SetString(getDataSourceException("Error"), exc.what());
         return (NULL);