PyObject* dataobj;
PyObject* retval = NULL;
DBT key, data;
+ void *orig_data;
DB_TXN *txn = NULL;
static char* kwnames[] = { "key", "data", "txn", "flags", NULL };
CHECK_DB_NOT_CLOSED(self);
if (!make_key_dbt(self, keyobj, &key, NULL))
return NULL;
- CLEAR_DBT(data);
if ( !make_dbt(dataobj, &data) ||
!checkTxnObj(txnobj, &txn) )
{
}
flags |= DB_GET_BOTH;
+ orig_data = data.data;
if (CHECK_DBFLAG(self, DB_THREAD)) {
/* Tell BerkeleyDB to malloc the return value (thread safe) */
+ /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
data.flags = DB_DBT_MALLOC;
- /* TODO: Is this flag needed? We're passing a data object that should
- match what's in the DB, so there should be no need to malloc.
- We run the risk of freeing something twice! Check this. */
}
MYDB_BEGIN_ALLOW_THREADS;
retval = Py_None;
}
else if (!err) {
+ /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
retval = PyString_FromStringAndSize((char*)data.data, data.size);
- FREE_DBT(data); /* Only if retrieval was successful */
+
+ /* Even though the flags require DB_DBT_MALLOC, data is not always
+ allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
+ if (data.data != orig_data)
+ FREE_DBT(data);
}
FREE_DBT(key);