You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2011/08/23 22:35:48 UTC
svn commit: r1160884 - in /subversion/branches/fs-py/subversion:
libsvn_fs_py/fs_fs.c libsvn_fs_py/py_util.c libsvn_fs_py/py_util.h
python/svn/__init__.py python/svn/fs/__init__.py
Author: hwright
Date: Tue Aug 23 20:35:48 2011
New Revision: 1160884
URL: http://svn.apache.org/viewvc?rev=1160884&view=rev
Log:
On the fs-py branch:
A couple of steps toward getting pack implemented in Python. Right now, all
this does is call the Python method which grabs a lock and checks for
cancellation. The bulk of this commit is dedicated to locking and improved
error handling.
* subversion/python/svn/__init__.py
(SubversionException._new_from_err_list): New.
* subversion/python/svn/fs/__init__.py
(FS.__init__): Get a lock object.
(FS.pack): Grab the lock, and notify and check for cancellation.
* subversion/libsvn_fs_py/fs_fs.c
(svn_fs_py__pack): Wrap the cancellation and notify functions, and call the
Python pack method.
* subversion/libsvn_fs_py/py_util.c
(raise_and_clear_err): New.
(svn_fs_py__wrap_pack_notify_func, cancel_func_wrapper,
svn_fs_py__wrap_cancel_func): New.
* subversion/libsvn_fs_py/py_util.h
(svn_fs_py__wrap_pack_notify_func, svn_fs_py__wrap_cancel_func): New.
Modified:
subversion/branches/fs-py/subversion/libsvn_fs_py/fs_fs.c
subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.c
subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.h
subversion/branches/fs-py/subversion/python/svn/__init__.py
subversion/branches/fs-py/subversion/python/svn/fs/__init__.py
Modified: subversion/branches/fs-py/subversion/libsvn_fs_py/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_fs_py/fs_fs.c?rev=1160884&r1=1160883&r2=1160884&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_fs_py/fs_fs.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_fs_py/fs_fs.c Tue Aug 23 20:35:48 2011
@@ -7327,12 +7327,23 @@ svn_fs_py__pack(svn_fs_t *fs,
void *cancel_baton,
apr_pool_t *pool)
{
+ fs_fs_data_t *ffd = fs->fsap_data;
struct pack_baton pb = { 0 };
+ PyObject *p_cancel_func;
+ PyObject *p_notify_func;
+
pb.fs = fs;
pb.notify_func = notify_func;
pb.notify_baton = notify_baton;
pb.cancel_func = cancel_func;
pb.cancel_baton = cancel_baton;
+
+ p_notify_func = svn_fs_py__wrap_pack_notify_func(notify_func, notify_baton);
+ p_cancel_func = svn_fs_py__wrap_cancel_func(cancel_func, cancel_baton);
+
+ SVN_ERR(svn_fs_py__call_method(NULL, ffd->p_fs, "pack", "(NN)",
+ p_notify_func, p_cancel_func));
+
return svn_fs_py__with_write_lock(fs, pack_body, &pb, pool);
}
Modified: subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.c?rev=1160884&r1=1160883&r2=1160884&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.c Tue Aug 23 20:35:48 2011
@@ -209,6 +209,123 @@ load_error:
}
}
+static void
+raise_and_clear_err(svn_error_t *error_chain)
+{
+ PyObject *args_list = NULL;
+ PyObject *args = NULL;
+ PyObject *apr_err_ob = NULL;
+ PyObject *message_ob = NULL;
+ PyObject *file_ob = NULL;
+ PyObject *line_ob = NULL;
+ PyObject *svn_module = NULL;
+ PyObject *exc_class = NULL;
+ PyObject *exc_ob = NULL;
+ svn_error_t *err;
+
+ if (error_chain == NULL)
+ return;
+
+ args_list = PyList_New(0);
+ if (PyErr_Occurred())
+ goto finished;
+
+ for (err = error_chain; err; err = err->child)
+ {
+ int i;
+
+ args = PyTuple_New(4);
+ if (PyErr_Occurred())
+ goto finished;
+
+ /* Convert the fields of the svn_error_t to Python objects. */
+ apr_err_ob = PyInt_FromLong(err->apr_err);
+ if (PyErr_Occurred())
+ goto finished;
+
+ if (err->message)
+ {
+ message_ob = PyString_FromString(err->message);
+ if (PyErr_Occurred())
+ goto finished;
+ }
+ else
+ {
+ Py_INCREF(Py_None);
+ message_ob = Py_None;
+ }
+
+ if (err->file)
+ {
+ file_ob = PyString_FromString(err->file);
+ if (PyErr_Occurred())
+ goto finished;
+ }
+ else
+ {
+ Py_INCREF(Py_None);
+ file_ob = Py_None;
+ }
+
+ line_ob = PyInt_FromLong(err->line);
+ if (PyErr_Occurred())
+ goto finished;
+
+ /* Store the objects in the tuple. */
+ i = 0;
+#define append(item) \
+ if (PyTuple_SetItem(args, i++, item) == 0) \
+ /* tuple stole our reference, so don't DECREF */ \
+ item = NULL; \
+ else \
+ goto finished;
+ append(apr_err_ob);
+ append(message_ob);
+ append(file_ob);
+ append(line_ob);
+#undef append
+
+ /* Append the tuple to the args list. */
+ PyList_Append(args_list, args);
+ if (PyErr_Occurred())
+ goto finished;
+
+ /* The list takes its own reference, so release ours. */
+ Py_DECREF(args);
+ }
+ args = NULL;
+ svn_error_clear(error_chain);
+
+ /* Create the exception object chain. */
+ svn_module = PyImport_ImportModule((char *)"svn");
+ if (PyErr_Occurred())
+ goto finished;
+
+ exc_class = PyObject_GetAttrString(svn_module, (char *)"SubversionException");
+ if (PyErr_Occurred())
+ goto finished;
+
+ exc_ob = PyObject_CallMethod(exc_class, (char *)"_new_from_err_list",
+ (char *)"(O)", args_list);
+ if (PyErr_Occurred())
+ goto finished;
+
+ /* Raise the exception. */
+ PyErr_SetObject(exc_class, exc_ob);
+
+ finished:
+ /* Release any references. */
+ Py_XDECREF(args_list);
+ Py_XDECREF(args);
+ Py_XDECREF(apr_err_ob);
+ Py_XDECREF(message_ob);
+ Py_XDECREF(file_ob);
+ Py_XDECREF(line_ob);
+ Py_XDECREF(svn_module);
+ Py_XDECREF(exc_class);
+ Py_XDECREF(exc_ob);
+}
+
svn_error_t *
svn_fs_py__init_python(apr_pool_t *pool)
{
@@ -502,3 +619,73 @@ svn_fs_py__load_module(fs_fs_data_t *ffd
{
return svn_error_trace(load_module(&ffd->p_module, FS_MODULE_NAME));
}
+
+PyObject *
+svn_fs_py__wrap_pack_notify_func(svn_fs_pack_notify_t notify_func,
+ void *notify_baton)
+{
+ if (!notify_func)
+ Py_RETURN_NONE;
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+cancel_func_wrapper(PyObject *p_tuple, PyObject *args)
+{
+ PyObject *c_func;
+ PyObject *baton;
+ void *cancel_baton;
+ svn_cancel_func_t cancel_func;
+ svn_error_t *err;
+
+ c_func = PySequence_GetItem(p_tuple, 0);
+ cancel_func = PyCObject_AsVoidPtr(c_func);
+ Py_DECREF(c_func);
+
+ baton = PySequence_GetItem(p_tuple, 1);
+ if (baton == Py_None)
+ cancel_baton = NULL;
+ else
+ cancel_baton = PyCObject_AsVoidPtr(baton);
+ Py_DECREF(baton);
+
+ err = cancel_func(cancel_baton);
+ if (err)
+ raise_and_clear_err(err);
+
+ Py_RETURN_NONE;
+}
+
+PyObject *
+svn_fs_py__wrap_cancel_func(svn_cancel_func_t cancel_func,
+ void *cancel_baton)
+{
+ static PyMethodDef method_def = { "cancel", cancel_func_wrapper,
+ METH_NOARGS, NULL };
+ PyObject *func;
+ PyObject *c_func;
+ PyObject *baton;
+ PyObject *p_tuple;
+
+ if (!cancel_func)
+ Py_RETURN_NONE;
+
+ c_func = PyCObject_FromVoidPtr(cancel_func, NULL);
+
+ if (cancel_baton)
+ {
+ baton = PyCObject_FromVoidPtr(cancel_baton, NULL);
+ }
+ else
+ {
+ baton = Py_None;
+ Py_INCREF(baton);
+ }
+
+ p_tuple = Py_BuildValue("(NN)", c_func, baton);
+ func = PyCFunction_New(&method_def, p_tuple);
+ Py_DECREF(p_tuple);
+
+ return func;
+}
Modified: subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.h
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.h?rev=1160884&r1=1160883&r2=1160884&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.h (original)
+++ subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.h Tue Aug 23 20:35:48 2011
@@ -67,3 +67,11 @@ svn_error_t *
svn_fs_py__get_int_attr(int *result,
PyObject *p_obj,
const char *name);
+
+PyObject *
+svn_fs_py__wrap_pack_notify_func(svn_fs_pack_notify_t notify_func,
+ void *notify_baton);
+
+PyObject *
+svn_fs_py__wrap_cancel_func(svn_cancel_func_t cancel_func,
+ void *cancel_baton);
Modified: subversion/branches/fs-py/subversion/python/svn/__init__.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/python/svn/__init__.py?rev=1160884&r1=1160883&r2=1160884&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/python/svn/__init__.py (original)
+++ subversion/branches/fs-py/subversion/python/svn/__init__.py Tue Aug 23 20:35:48 2011
@@ -27,6 +27,16 @@ class SubversionException(Exception):
def __str__(self):
return self.message
+ @classmethod
+ def _new_from_err_list(cls, errors):
+ '''This is provided for any C callers to manually construct an
+ exception.'''
+ child = None
+ errors.reverse()
+ for (apr_err, message, file, line) in errors:
+ child = cls(apr_err, message)
+ return child
+
def is_valid_revnum(rev):
return rev >= 0
Modified: subversion/branches/fs-py/subversion/python/svn/fs/__init__.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/python/svn/fs/__init__.py?rev=1160884&r1=1160883&r2=1160884&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/python/svn/fs/__init__.py (original)
+++ subversion/branches/fs-py/subversion/python/svn/fs/__init__.py Tue Aug 23 20:35:48 2011
@@ -25,6 +25,7 @@ import svn
import svn.hash
import svn.prop
import svn._cache
+import svn._lock
import svn.err
# Some constants
@@ -439,6 +440,18 @@ class FS(object):
else:
self._open_fs()
+ self._write_lock = svn._lock.Lock(self.__path_lock)
+
+
+ def pack(self, notify=None, cancel=None):
+ 'Pack the filesystem, calling NOTIFY and CANCEL as appropriate.'
+
+ with self._write_lock:
+ if notify:
+ notify()
+ if cancel:
+ cancel()
+
# A few helper functions for C callers