support BLOCKING keyword

This commit is contained in:
David Rose 2007-04-18 21:51:36 +00:00
parent 3d86e7bf8b
commit 346928ece7
7 changed files with 53 additions and 1 deletions

View File

@ -236,6 +236,7 @@ pop_struct() {
%token TOKENPASTE
%token KW_BEGIN_PUBLISH
%token KW_BLOCKING
%token KW_BOOL
%token KW_CATCH
%token KW_CHAR
@ -531,6 +532,10 @@ storage_class:
| storage_class KW_REGISTER
{
$$ = $1 | (int)CPPInstance::SC_register;
}
| storage_class KW_BLOCKING
{
$$ = $1 | (int)CPPInstance::SC_blocking;
}
;

View File

@ -54,6 +54,12 @@ public:
// This bit is only set by CPPStructType::check_virtual().
SC_inherited_virtual = 0x400,
// This is a special "storage class" for methods tagged with the
// BLOCKING macro (i.e. the special __blocking keyword). These
// are methods that might block and therefore need to release
// Python threads for their duration.
SC_blocking = 0x800,
};
CPPInstance(CPPType *type, const string &name, int storage_class = 0);

View File

@ -1929,6 +1929,7 @@ get_number(int c, int c2) {
int CPPPreprocessor::
check_keyword(const string &name) {
if (name == "__begin_publish") return KW_BEGIN_PUBLISH;
if (name == "__blocking") return KW_BLOCKING;
if (name == "bool") return KW_BOOL;
if (name == "catch") return KW_CATCH;
if (name == "char") return KW_CHAR;

View File

@ -277,15 +277,19 @@
/*
We define the macros BEGIN_PUBLISH and END_PUBLISH to bracket
functions and global variable definitions that are to be published
via interrogate to scripting languages.
via interrogate to scripting languages. Also, the macro BLOCKING is
used to flag any function or method that might perform I/O blocking
and thus needs to release Python threads for its duration.
*/
#ifdef CPPPARSER
#define BEGIN_PUBLISH __begin_publish
#define END_PUBLISH __end_publish
#define BLOCKING __blocking
#undef USE_STL_ALLOCATOR // Don't try to parse these template classes in interrogate.
#else
#define BEGIN_PUBLISH
#define END_PUBLISH
#define BLOCKING
#endif
#ifdef __cplusplus

View File

@ -47,6 +47,7 @@ FunctionRemap(const InterrogateType &itype, const InterrogateFunction &ifunc,
_void_return = true;
_ForcedVoidReturn = false;
_has_this = false;
_blocking = false;
_const_method = false;
_first_true_parameter = 0;
_num_default_parameters = num_default_parameters;
@ -438,6 +439,12 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
_type = T_setter;
}
if (_cpptype != (CPPType *)NULL &&
((_cppfunc->_storage_class & CPPInstance::SC_blocking) != 0)) {
// If it's marked as a "blocking" method or function, record that.
_blocking = true;
}
if (_cpptype != (CPPType *)NULL &&
((_cppfunc->_storage_class & CPPInstance::SC_static) == 0) &&
_type != T_constructor) {

View File

@ -89,6 +89,7 @@ public:
bool _void_return;
bool _ForcedVoidReturn;
bool _has_this;
bool _blocking;
bool _const_method;
int _first_true_parameter;
int _num_default_parameters;

View File

@ -2275,6 +2275,12 @@ void InterfaceMakerPythonNative::write_function_instance(ostream &out, Interface
remap->_return_type->new_type_is_atomic_string()) {
// Treat strings as a special case. We don't want to format the
// return expression.
if (remap->_blocking) {
indent(out, extra_indent_level)
<< "PyThreadState *_save;\n";
indent(out, extra_indent_level)
<< "Py_UNBLOCK_THREADS\n";
}
string tt;
string return_expr = remap->call_function(out, extra_indent_level, false, container, pexprs);
CPPType *type = remap->_return_type->get_orig_type();
@ -2282,6 +2288,11 @@ void InterfaceMakerPythonNative::write_function_instance(ostream &out, Interface
type->output_instance(out, "return_value", &parser);
// type->output_instance(tt, "return_value", &parser);
out << " = " << return_expr << ";\n";
if (remap->_blocking) {
indent(out, extra_indent_level)
<< "Py_BLOCK_THREADS\n";
}
if (track_interpreter) {
indent(out,extra_indent_level) << "in_interpreter = 1;\n";
@ -2295,8 +2306,20 @@ void InterfaceMakerPythonNative::write_function_instance(ostream &out, Interface
pack_return_value(out, extra_indent_level, remap, return_expr,ForwardDeclrs,is_inplace);
} else {
if (remap->_blocking) {
indent(out, extra_indent_level)
<< "PyThreadState *_save;\n";
indent(out, extra_indent_level)
<< "Py_UNBLOCK_THREADS\n";
}
string return_expr = remap->call_function(out, extra_indent_level, true, container, pexprs);
if (return_expr.empty()) {
if (remap->_blocking) {
indent(out, extra_indent_level)
<< "Py_BLOCK_THREADS\n";
}
if (track_interpreter) {
indent(out,extra_indent_level) << "in_interpreter = 1;\n";
}
@ -2313,6 +2336,11 @@ void InterfaceMakerPythonNative::write_function_instance(ostream &out, Interface
type->output_instance(out, "return_value", &parser);
out << " = " << return_expr << ";\n";
}
if (remap->_blocking) {
indent(out, extra_indent_level)
<< "Py_BLOCK_THREADS\n";
}
if (track_interpreter) {
indent(out,extra_indent_level) << "in_interpreter = 1;\n";
}