vfs: Show IOError instead of AssertionError if read_file fails

The methods are marked non-BLOCKING since the GIL needs to be held while throwing exceptions.  We handle the GIL in the extension functions instead.
This commit is contained in:
rdb 2017-06-20 21:52:04 +02:00
parent 3eb91e38b5
commit c6dda2a44a
4 changed files with 44 additions and 6 deletions

View File

@ -56,12 +56,12 @@ PUBLISHED:
BLOCKING void ls(ostream &out = cout) const;
BLOCKING void ls_all(ostream &out = cout) const;
EXTENSION(BLOCKING PyObject *read_file(bool auto_unwrap) const);
EXTENSION(PyObject *read_file(bool auto_unwrap) const);
BLOCKING virtual istream *open_read_file(bool auto_unwrap) const;
BLOCKING virtual void close_read_file(istream *stream) const;
virtual bool was_read_successful() const;
EXTENSION(BLOCKING PyObject *write_file(PyObject *data, bool auto_wrap));
EXTENSION(PyObject *write_file(PyObject *data, bool auto_wrap));
BLOCKING virtual ostream *open_write_file(bool auto_wrap, bool truncate);
BLOCKING virtual ostream *open_append_file();
BLOCKING virtual void close_write_file(ostream *stream);

View File

@ -95,11 +95,11 @@ PUBLISHED:
static VirtualFileSystem *get_global_ptr();
EXTENSION(BLOCKING PyObject *read_file(const Filename &filename, bool auto_unwrap) const);
EXTENSION(PyObject *read_file(const Filename &filename, bool auto_unwrap) const);
BLOCKING istream *open_read_file(const Filename &filename, bool auto_unwrap) const;
BLOCKING static void close_read_file(istream *stream);
EXTENSION(BLOCKING PyObject *write_file(const Filename &filename, PyObject *data, bool auto_wrap));
EXTENSION(PyObject *write_file(const Filename &filename, PyObject *data, bool auto_wrap));
BLOCKING ostream *open_write_file(const Filename &filename, bool auto_wrap, bool truncate);
BLOCKING ostream *open_append_file(const Filename &filename);
BLOCKING static void close_write_file(ostream *stream);

View File

@ -26,9 +26,22 @@
*/
PyObject *Extension<VirtualFileSystem>::
read_file(const Filename &filename, bool auto_unwrap) const {
// Release the GIL while we do this potentially slow operation.
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
PyThreadState *_save;
Py_UNBLOCK_THREADS
#endif
vector_uchar pv;
bool okflag = _this->read_file(filename, pv, auto_unwrap);
nassertr(okflag, NULL);
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
Py_BLOCK_THREADS
#endif
if (!okflag) {
return PyErr_Format(PyExc_IOError, "Failed to read file: '%s'", filename.c_str());
}
#if PY_MAJOR_VERSION >= 3
if (pv.empty()) {

View File

@ -26,9 +26,23 @@
*/
PyObject *Extension<VirtualFile>::
read_file(bool auto_unwrap) const {
// Release the GIL while we do this potentially slow operation.
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
PyThreadState *_save;
Py_UNBLOCK_THREADS
#endif
vector_uchar pv;
bool okflag = _this->read_file(pv, auto_unwrap);
nassertr(okflag, NULL);
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
Py_BLOCK_THREADS
#endif
if (!okflag) {
Filename fn = _this->get_filename();
return PyErr_Format(PyExc_IOError, "Failed to read file: '%s'", fn.c_str());
}
#if PY_MAJOR_VERSION >= 3
if (pv.empty()) {
@ -68,7 +82,18 @@ write_file(PyObject *data, bool auto_wrap) {
}
#endif
// Release the GIL while we do this potentially slow operation.
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
PyThreadState *_save;
Py_UNBLOCK_THREADS
#endif
bool result = _this->write_file((const unsigned char *)buffer, length, auto_wrap);
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
Py_BLOCK_THREADS
#endif
return PyBool_FromLong(result);
}