Rev 1077: Fix more memory management issues. in file:///data/jelmer/bzr-svn/cext/

Jelmer Vernooij jelmer at samba.org
Wed Jun 4 23:09:10 BST 2008


At file:///data/jelmer/bzr-svn/cext/

------------------------------------------------------------
revno: 1077
revision-id: jelmer at samba.org-20080604220909-jowzix6ayo7otc2w
parent: jelmer at samba.org-20080604212042-2v93z80f0oh3vrpt
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: cext
timestamp: Thu 2008-06-05 00:09:09 +0200
message:
  Fix more memory management issues.
modified:
  core.c                         core.pyx-20080313210413-17k59slolpfe5kdq-1
  editor.c                       editor.c-20080602191336-frj7az1sdk13o1tw-1
  editor.h                       editor.h-20080602191336-frj7az1sdk13o1tw-2
  ra.c                           ra.pyx-20080313140933-qybkqaxe3m4mcll7-1
  tests/test_ra.py               test_ra.py-20080313141743-uzsm7ejitrlqone5-1
  wc.c                           wc.pyx-20080313142018-10l8l23vha2j9e6b-1
=== modified file 'core.c'
--- a/core.c	2008-06-04 21:20:42 +0000
+++ b/core.c	2008-06-04 22:09:09 +0000
@@ -70,6 +70,7 @@
 	PyObject_HEAD_INIT(NULL) 0,
 	.tp_name = "core.Config",
 	.tp_basicsize = sizeof(ConfigObject),
+	.tp_dealloc = (destructor)PyObject_Del,
 };
 
 static PyObject *get_config(PyObject *self, PyObject *args)

=== modified file 'editor.c'
--- a/editor.c	2008-06-04 21:20:42 +0000
+++ b/editor.c	2008-06-04 22:09:09 +0000
@@ -29,10 +29,11 @@
     const svn_delta_editor_t *editor;
     void *baton;
     apr_pool_t *pool;
-	bool *busy_var;
+	PyObject *(*done_cb) (void *baton);
+	void *done_baton;
 } EditorObject;
 
-PyObject *new_editor_object(const svn_delta_editor_t *editor, void *baton, apr_pool_t *pool, PyTypeObject *type, bool *busy_var)
+PyObject *new_editor_object(const svn_delta_editor_t *editor, void *baton, apr_pool_t *pool, PyTypeObject *type, PyObject *(*done_cb) (void *), void *done_baton)
 {
 	EditorObject *obj = PyObject_New(EditorObject, type);
 	if (obj == NULL)
@@ -40,7 +41,8 @@
 	obj->editor = editor;
     obj->baton = baton;
 	obj->pool = pool;
-	obj->busy_var = busy_var;
+	obj->done_cb = done_cb;
+	obj->done_baton = done_baton;
 	return (PyObject *)obj;
 }
 
@@ -54,6 +56,7 @@
 
 PyTypeObject TxDeltaWindowHandler_Type = {
 	PyObject_HEAD_INIT(&PyType_Type) 0,
+	.tp_basicsize = sizeof(TxDeltaWindowHandlerObject),
 	.tp_name = "ra.TxDeltaWindowHandler",
 	.tp_call = NULL, /* FIXME */
 	.tp_dealloc = (destructor)PyObject_Del
@@ -131,6 +134,7 @@
 PyTypeObject FileEditor_Type = { 
 	PyObject_HEAD_INIT(&PyType_Type) 0,
 	.tp_name = "ra.FileEditor",
+	.tp_basicsize = sizeof(EditorObject),
 	.tp_methods = py_file_editor_methods,
 	.tp_dealloc = (destructor)PyObject_Del,
 };
@@ -177,7 +181,7 @@
 		return NULL;
 
     return new_editor_object(editor->editor, child_baton, editor->pool, 
-							 &DirectoryEditor_Type, NULL);
+							 &DirectoryEditor_Type, NULL, NULL);
 }
 
 static PyObject *py_dir_editor_open_directory(PyObject *self, PyObject *args)
@@ -200,7 +204,7 @@
 		return NULL;
 
     return new_editor_object(editor->editor, child_baton, editor->pool, 
-							 &DirectoryEditor_Type, NULL);
+							 &DirectoryEditor_Type, NULL, NULL);
 }
 
 static PyObject *py_dir_editor_change_prop(PyObject *self, PyObject *args)
@@ -283,7 +287,7 @@
 		return NULL;
 
 	return new_editor_object(editor->editor, file_baton, editor->pool,
-							 &FileEditor_Type, NULL);
+							 &FileEditor_Type, NULL, NULL);
 }
 
 static PyObject *py_dir_editor_open_file(PyObject *self, PyObject *args)
@@ -306,7 +310,7 @@
 		return NULL;
 
 	return new_editor_object(editor->editor, file_baton, editor->pool,
-							 &FileEditor_Type, NULL);
+							 &FileEditor_Type, NULL, NULL);
 }
 
 static PyObject *py_dir_editor_absent_file(PyObject *self, PyObject *args)
@@ -345,6 +349,7 @@
 PyTypeObject DirectoryEditor_Type = { 
 	PyObject_HEAD_INIT(&PyType_Type) 0,
 	.tp_name = "ra.DirEditor",
+	.tp_basicsize = sizeof(EditorObject),
 	.tp_methods = py_dir_editor_methods,
 	.tp_dealloc = (destructor)PyObject_Del,
 };
@@ -388,7 +393,7 @@
 		return NULL;
 
 	return new_editor_object(editor->editor, root_baton, editor->pool,
-							 &DirectoryEditor_Type, NULL);
+							 &DirectoryEditor_Type, NULL, NULL);
 }
 
 static PyObject *py_editor_close(PyObject *self)
@@ -403,8 +408,8 @@
 	if (!check_error(editor->editor->close_edit(editor->baton, editor->pool)))
 		return NULL;
 
-	if (editor->busy_var != NULL)
-		*editor->busy_var = false;
+	if (editor->done_cb != NULL)
+		editor->done_cb(editor->done_baton);
 
 	Py_RETURN_NONE;
 }
@@ -421,9 +426,9 @@
 	if (!check_error(editor->editor->abort_edit(editor->baton, editor->pool)))
 		return NULL;
 
-	if (editor->busy_var != NULL)
-		*editor->busy_var = false;
-
+	if (editor->done_cb != NULL)
+		editor->done_cb(editor->done_baton);
+	
 	Py_RETURN_NONE;
 }
 
@@ -438,6 +443,7 @@
 PyTypeObject Editor_Type = { 
 	PyObject_HEAD_INIT(&PyType_Type) 0,
 	.tp_name = "ra.Editor",
+	.tp_basicsize = sizeof(EditorObject),
 	.tp_methods = py_editor_methods,
 	.tp_dealloc = py_editor_dealloc,
 };

=== modified file 'editor.h'
--- a/editor.h	2008-06-04 21:20:42 +0000
+++ b/editor.h	2008-06-04 22:09:09 +0000
@@ -26,7 +26,7 @@
 PyAPI_DATA(PyTypeObject) FileEditor_Type;
 PyAPI_DATA(PyTypeObject) Editor_Type;
 PyAPI_DATA(PyTypeObject) TxDeltaWindowHandler_Type;
-PyObject *new_editor_object(const svn_delta_editor_t *editor, void *baton, apr_pool_t *pool, PyTypeObject *type, bool *busy_var);
+PyObject *new_editor_object(const svn_delta_editor_t *editor, void *baton, apr_pool_t *pool, PyTypeObject *type, PyObject *(*done_cb) (void *baton), void *done_baton);
 
 #define DirectoryEditor_Check(op) PyObject_TypeCheck(op, &DirectoryEditor_Type)
 #define FileEditor_Check(op) PyObject_TypeCheck(op, &FileEditor_Type)

=== modified file 'ra.c'
--- a/ra.c	2008-06-04 21:20:42 +0000
+++ b/ra.c	2008-06-04 22:09:09 +0000
@@ -91,14 +91,24 @@
 	Py_DECREF(ret);
 }
 
-#define RA_UNBUSY(pool, ra) ra->busy = false;
+#define RA_UNBUSY(pool, ra) \
+	ra->busy = false; \
+	if (ra->unbusy_cb != Py_None) { \
+		PyObject *ret = PyObject_CallFunction(ra->unbusy_cb, ""); \
+		if (ret == NULL) { \
+			apr_pool_destroy(pool); \
+			return NULL; \
+		} \
+	} 
+
 
 typedef struct {
 	PyObject_HEAD
     const svn_ra_reporter2_t *reporter;
     void *report_baton;
     apr_pool_t *pool;
-	bool *busy_var;
+	PyObject *(*done_cb)(void *baton);
+	void *done_baton;
 } ReporterObject;
 
 static PyObject *reporter_set_path(PyObject *self, PyObject *args)
@@ -160,8 +170,8 @@
 													  reporter->pool)))
 		return NULL;
 
-	if (reporter->busy_var != NULL)
-		*reporter->busy_var = false;
+	if (reporter->done_cb != NULL)
+		reporter->done_cb(reporter->done_baton);
 
 	Py_RETURN_NONE;
 }
@@ -173,8 +183,8 @@
 													 reporter->pool)))
 		return NULL;
 
-	if (reporter->busy_var != NULL)
-		*reporter->busy_var = false;
+	if (reporter->done_cb != NULL)
+		reporter->done_cb(reporter->done_baton);
 
 	Py_RETURN_NONE;
 }
@@ -199,6 +209,7 @@
 PyTypeObject Reporter_Type = {
 	PyObject_HEAD_INIT(NULL) 0,
 	.tp_name = "ra.Reporter",
+	.tp_basicsize = sizeof(ReporterObject),
 	.tp_methods = reporter_methods,
 	.tp_dealloc = reporter_dealloc,
 };
@@ -480,9 +491,18 @@
     PyObject *progress_func;
 	AuthObject *auth;
 	bool busy;
-	PyObject *unbusy_handler;
+	PyObject *unbusy_cb;
 } RemoteAccessObject;
 
+static PyObject *ra_done_handler(void *_ra)
+{
+	RemoteAccessObject *ra = (RemoteAccessObject *)_ra;
+
+	RA_UNBUSY(NULL, ra);
+
+	Py_RETURN_NONE;
+}
+
 static bool ra_check_busy(RemoteAccessObject *raobj)
 {
 	if (raobj->busy) {
@@ -533,6 +553,9 @@
 		ret->auth = auth;
 		auth_baton = ret->auth->auth_baton;
 	}
+
+	ret->unbusy_cb = Py_None;
+	Py_INCREF(ret->unbusy_cb);
 	
     ret->pool = Pool();
 	if (ret->pool == NULL)
@@ -724,6 +747,8 @@
 	temp_pool = Pool();
 	if (temp_pool == NULL)
 		return NULL;
+
+	Py_INCREF(update_editor);
 	RUN_SVN_WITH_POOL(temp_pool, svn_ra_do_update(ra->ra, &reporter, 
 												  &report_baton, 
 												  revision_to_update_to, 
@@ -736,7 +761,8 @@
 	ret->reporter = reporter;
 	ret->report_baton = report_baton;
 	ret->pool = temp_pool;
-	ret->busy_var = &ra->busy;
+	ret->done_cb = ra_done_handler;
+	ret->done_baton = ra;
 	return (PyObject *)ret;
 }
 
@@ -762,6 +788,7 @@
 	temp_pool = Pool();
 	if (temp_pool == NULL)
 		return NULL;
+	Py_INCREF(update_editor);
 	RUN_SVN_WITH_POOL(temp_pool, svn_ra_do_switch(
 						ra->ra, &reporter, &report_baton, 
 						revision_to_update_to, update_target, 
@@ -773,7 +800,8 @@
 	ret->reporter = reporter;
 	ret->report_baton = report_baton;
 	ret->pool = temp_pool;
-	ret->busy_var = &ra->busy;
+	ret->done_cb = ra_done_handler;
+	ret->done_baton = ra;
 	return (PyObject *)ret;
 }
 
@@ -794,6 +822,7 @@
 	temp_pool = Pool();
 	if (temp_pool == NULL)
 		return NULL;
+	Py_INCREF(update_editor);
     RUN_SVN_WITH_POOL(temp_pool, 
 					  svn_ra_replay(ra->ra, revision, low_water_mark,
 									send_deltas, &py_editor, update_editor, 
@@ -875,7 +904,7 @@
 		commit_callback, hash_lock_tokens, keep_locks, pool));
 	apr_pool_destroy(temp_pool);
 	return new_editor_object(editor, edit_baton, pool, 
-								  &Editor_Type, &ra->busy);
+								  &Editor_Type, ra_done_handler, ra);
 }
 
 static PyObject *ra_change_rev_prop(PyObject *self, PyObject *args)
@@ -1226,8 +1255,10 @@
 static void ra_dealloc(PyObject *self)
 {
 	RemoteAccessObject *ra = (RemoteAccessObject *)self;
+	Py_XDECREF(ra->unbusy_cb);
 	apr_pool_destroy(ra->pool);
 	Py_XDECREF(ra->auth);
+	PyObject_Del(self);
 }
 
 static PyObject *ra_repr(PyObject *self)
@@ -1238,7 +1269,18 @@
 
 static PyObject *ra_set_unbusy_handler(PyObject *self, PyObject *args)
 {
-	Py_RETURN_NONE; /* FIXME */
+	RemoteAccessObject *ra = (RemoteAccessObject *)self;
+	PyObject *unbusy_func;
+
+	if (!PyArg_ParseTuple(args, "O", &unbusy_func))
+		return NULL;
+
+	Py_DECREF (ra->unbusy_cb);
+
+	ra->unbusy_cb = unbusy_func;
+	Py_INCREF(ra->unbusy_cb);
+
+	Py_RETURN_NONE;
 }
 
 static PyMethodDef ra_methods[] = {

=== modified file 'tests/test_ra.py'
--- a/tests/test_ra.py	2008-06-04 19:46:38 +0000
+++ b/tests/test_ra.py	2008-06-04 22:09:09 +0000
@@ -23,6 +23,7 @@
     def test_version_length(self):
         self.assertEquals(4, len(ra.version()))
 
+
 class TestRemoteAccess(TestCaseWithSubversionRepository):
     def setUp(self):
         super(TestRemoteAccess, self).setUp()
@@ -89,10 +90,20 @@
         self.assertEquals(set(["svn:date", "svn:author", "svn:log"]), 
                           set(props.keys()))
 
-    def test_get_commit_editor(self):
+    def test_get_commit_editor_busy(self):
         def mycb(rev):
             pass
         editor = self.ra.get_commit_editor({"svn:log": "foo"}, mycb)
         self.assertRaises(ra.BusyException, self.ra.get_commit_editor, {"svn:log": "foo"}, mycb)
         editor.abort()
 
+    def test_get_commit_editor(self):
+        def mycb(paths, rev, revprops):
+            pass
+        editor = self.ra.get_commit_editor({"svn:log": "foo"}, mycb)
+        dir = editor.open_root(0)
+        subdir = dir.add_directory("foo")
+        subdir.close()
+        dir.close()
+        editor.close()
+

=== modified file 'wc.c'
--- a/wc.c	2008-06-04 21:20:42 +0000
+++ b/wc.c	2008-06-04 22:09:09 +0000
@@ -497,7 +497,7 @@
 		apr_pool_destroy(pool);
 		return NULL;
 	}
-	return new_editor_object(editor, edit_baton, pool, &Editor_Type, NULL);
+	return new_editor_object(editor, edit_baton, pool, &Editor_Type, NULL, NULL);
 }
 
 static PyObject *adm_close(PyObject *self)




More information about the bazaar-commits mailing list