Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
a80ce036
Commit
a80ce036
authored
Dec 10, 2020
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Introduce 'locked' qualifier and refactor locking
parent
a66ffc46
Changes
14
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
79 additions
and
561 deletions
+79
-561
Cython/Compiler/Builtin.py
Cython/Compiler/Builtin.py
+5
-5
Cython/Compiler/CypclassTransforms.py
Cython/Compiler/CypclassTransforms.py
+26
-397
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+8
-7
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+0
-7
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+6
-4
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+2
-12
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+3
-4
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+4
-2
tests/errors/cypclass_lock_error.pyx
tests/errors/cypclass_lock_error.pyx
+0
-43
tests/run/cypclass_acthon.pyx
tests/run/cypclass_acthon.pyx
+16
-18
tests/run/cypclass_exception_refcount.pyx
tests/run/cypclass_exception_refcount.pyx
+1
-1
tests/run/cypclass_inplace_operator_inference.pyx
tests/run/cypclass_inplace_operator_inference.pyx
+5
-5
tests/run/cypclass_lock.pyx
tests/run/cypclass_lock.pyx
+0
-53
tests/run/cypclass_nested_classes.pyx
tests/run/cypclass_nested_classes.pyx
+3
-3
No files found.
Cython/Compiler/Builtin.py
View file @
a80ce036
...
@@ -415,7 +415,7 @@ def inject_acthon_interfaces(self):
...
@@ -415,7 +415,7 @@ def inject_acthon_interfaces(self):
init_scope
(
result_scope
)
init_scope
(
result_scope
)
acthon_result_type
=
result_type
=
PyrexTypes
.
CypClassType
(
acthon_result_type
=
result_type
=
PyrexTypes
.
CypClassType
(
"ActhonResultInterface"
,
result_scope
,
"ActhonResultInterface"
,
(
PyrexTypes
.
cy_object_type
,),
"ActhonResultInterface"
,
result_scope
,
"ActhonResultInterface"
,
(
PyrexTypes
.
cy_object_type
,),
lock_mode
=
"autolock"
,
activable
=
False
)
activable
=
False
)
result_scope
.
type
=
result_type
result_scope
.
type
=
result_type
#result_type.set_scope is required because parent_type is used when doing scope inheritance
#result_type.set_scope is required because parent_type is used when doing scope inheritance
result_type
.
set_scope
(
result_scope
)
result_type
.
set_scope
(
result_scope
)
...
@@ -474,7 +474,7 @@ def inject_acthon_interfaces(self):
...
@@ -474,7 +474,7 @@ def inject_acthon_interfaces(self):
init_scope
(
message_scope
)
init_scope
(
message_scope
)
acthon_message_type
=
message_type
=
PyrexTypes
.
CypClassType
(
acthon_message_type
=
message_type
=
PyrexTypes
.
CypClassType
(
"ActhonMessageInterface"
,
message_scope
,
"ActhonMessageInterface"
,
(
PyrexTypes
.
cy_object_type
,),
"ActhonMessageInterface"
,
message_scope
,
"ActhonMessageInterface"
,
(
PyrexTypes
.
cy_object_type
,),
lock_mode
=
"autolock"
,
activable
=
False
)
activable
=
False
)
message_type
.
set_scope
(
message_scope
)
message_type
.
set_scope
(
message_scope
)
message_scope
.
type
=
message_type
message_scope
.
type
=
message_type
...
@@ -488,7 +488,7 @@ def inject_acthon_interfaces(self):
...
@@ -488,7 +488,7 @@ def inject_acthon_interfaces(self):
init_scope
(
sync_scope
)
init_scope
(
sync_scope
)
acthon_sync_type
=
sync_type
=
PyrexTypes
.
CypClassType
(
acthon_sync_type
=
sync_type
=
PyrexTypes
.
CypClassType
(
"ActhonSyncInterface"
,
sync_scope
,
"ActhonSyncInterface"
,
(
PyrexTypes
.
cy_object_type
,),
"ActhonSyncInterface"
,
sync_scope
,
"ActhonSyncInterface"
,
(
PyrexTypes
.
cy_object_type
,),
lock_mode
=
"autolock"
,
activable
=
False
)
activable
=
False
)
sync_type
.
set_scope
(
sync_scope
)
sync_type
.
set_scope
(
sync_scope
)
sync_scope
.
type
=
sync_type
sync_scope
.
type
=
sync_type
sync_entry
=
self
.
declare
(
"ActhonSyncInterface"
,
"ActhonSyncInterface"
,
sync_type
,
None
,
"extern"
)
sync_entry
=
self
.
declare
(
"ActhonSyncInterface"
,
"ActhonSyncInterface"
,
sync_type
,
None
,
"extern"
)
...
@@ -557,7 +557,7 @@ def inject_acthon_interfaces(self):
...
@@ -557,7 +557,7 @@ def inject_acthon_interfaces(self):
init_scope
(
queue_scope
)
init_scope
(
queue_scope
)
acthon_queue_type
=
queue_type
=
PyrexTypes
.
CypClassType
(
acthon_queue_type
=
queue_type
=
PyrexTypes
.
CypClassType
(
"ActhonQueueInterface"
,
queue_scope
,
"ActhonQueueInterface"
,
(
PyrexTypes
.
cy_object_type
,),
"ActhonQueueInterface"
,
queue_scope
,
"ActhonQueueInterface"
,
(
PyrexTypes
.
cy_object_type
,),
lock_mode
=
"autolock"
,
activable
=
False
)
activable
=
False
)
queue_type
.
set_scope
(
queue_scope
)
queue_type
.
set_scope
(
queue_scope
)
queue_scope
.
type
=
queue_type
queue_scope
.
type
=
queue_type
queue_entry
=
self
.
declare
(
"ActhonQueueInterface"
,
"ActhonQueueInterface"
,
queue_type
,
self
,
"extern"
)
queue_entry
=
self
.
declare
(
"ActhonQueueInterface"
,
"ActhonQueueInterface"
,
queue_type
,
self
,
"extern"
)
...
@@ -594,7 +594,7 @@ def inject_acthon_interfaces(self):
...
@@ -594,7 +594,7 @@ def inject_acthon_interfaces(self):
init_scope
(
activable_scope
)
init_scope
(
activable_scope
)
acthon_activable_type
=
activable_type
=
PyrexTypes
.
CypClassType
(
acthon_activable_type
=
activable_type
=
PyrexTypes
.
CypClassType
(
"ActhonActivableClass"
,
activable_scope
,
"ActhonActivableClass"
,
(
PyrexTypes
.
cy_object_type
,),
"ActhonActivableClass"
,
activable_scope
,
"ActhonActivableClass"
,
(
PyrexTypes
.
cy_object_type
,),
lock_mode
=
"autolock"
,
activable
=
False
)
activable
=
False
)
activable_type
.
set_scope
(
activable_scope
)
activable_type
.
set_scope
(
activable_scope
)
activable_entry
=
self
.
declare
(
"ActhonActivableClass"
,
None
,
activable_type
,
"ActhonActivableClass"
,
"extern"
)
activable_entry
=
self
.
declare
(
"ActhonActivableClass"
,
None
,
activable_type
,
"ActhonActivableClass"
,
"extern"
)
activable_entry
.
is_type
=
1
activable_entry
.
is_type
=
1
...
...
Cython/Compiler/CypclassTransforms.py
View file @
a80ce036
This diff is collapsed.
Click to expand it.
Cython/Compiler/ExprNodes.py
View file @
a80ce036
...
@@ -7310,6 +7310,7 @@ class AttributeNode(ExprNode):
...
@@ -7310,6 +7310,7 @@ class AttributeNode(ExprNode):
return
node
return
node
def
analyse_types
(
self
,
env
,
target
=
0
):
def
analyse_types
(
self
,
env
,
target
=
0
):
self
.
is_target
=
target
self
.
initialized_check
=
env
.
directives
[
'initializedcheck'
]
self
.
initialized_check
=
env
.
directives
[
'initializedcheck'
]
node
=
self
.
analyse_as_cimported_attribute_node
(
env
,
target
)
node
=
self
.
analyse_as_cimported_attribute_node
(
env
,
target
)
if
node
is
None
and
not
target
:
if
node
is
None
and
not
target
:
...
@@ -14261,10 +14262,10 @@ class CoerceToTempNode(CoercionNode):
...
@@ -14261,10 +14262,10 @@ class CoerceToTempNode(CoercionNode):
class
CoerceToLockedNode
(
CoercionNode
):
class
CoerceToLockedNode
(
CoercionNode
):
# This node is used to lock a node of cypclass type around the evaluation of its subexpressions.
# This node is used to lock a node of cypclass type around the evaluation of its subexpressions.
#
rlock_only
boolean
#
exclusive
boolean
def
__init__
(
self
,
arg
,
env
=
None
,
rlock_only
=
Fals
e
):
def
__init__
(
self
,
arg
,
env
=
None
,
exclusive
=
Tru
e
):
self
.
rlock_only
=
rlock_only
self
.
exclusive
=
exclusive
self
.
type
=
arg
.
type
self
.
type
=
arg
.
type
arg
=
arg
.
coerce_to_temp
(
env
)
arg
=
arg
.
coerce_to_temp
(
env
)
arg
.
postpone_subexpr_disposal
=
True
arg
.
postpone_subexpr_disposal
=
True
...
@@ -14295,13 +14296,13 @@ class CoerceToLockedNode(CoercionNode):
...
@@ -14295,13 +14296,13 @@ class CoerceToLockedNode(CoercionNode):
# Create a scope to use scope bound resource management (RAII).
# Create a scope to use scope bound resource management (RAII).
code
.
putln
(
"{"
)
code
.
putln
(
"{"
)
# Since each lock guard has its o
nw
scope,
# Since each lock guard has its o
wn
scope,
# a prefix is enough to prevent name collisions.
# a prefix is enough to prevent name collisions.
guard_code
=
"%sguard"
%
Naming
.
cypclass_lock_guard_prefix
guard_code
=
"%sguard"
%
Naming
.
cypclass_lock_guard_prefix
if
self
.
rlock_only
:
if
self
.
exclusive
:
code
.
putln
(
"Cy_rlock_guard %s(%s, %s);"
%
(
guard_code
,
self
.
result
(),
context
))
else
:
code
.
putln
(
"Cy_wlock_guard %s(%s, %s);"
%
(
guard_code
,
self
.
result
(),
context
))
code
.
putln
(
"Cy_wlock_guard %s(%s, %s);"
%
(
guard_code
,
self
.
result
(),
context
))
else
:
code
.
putln
(
"Cy_rlock_guard %s(%s, %s);"
%
(
guard_code
,
self
.
result
(),
context
))
def
generate_disposal_code
(
self
,
code
):
def
generate_disposal_code
(
self
,
code
):
# Close the scope to release the lock.
# Close the scope to release the lock.
...
...
Cython/Compiler/ModuleNode.py
View file @
a80ce036
...
@@ -1209,13 +1209,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1209,13 +1209,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
reified_call_args_list
.
append
(
Naming
.
optional_args_cname
)
reified_call_args_list
.
append
(
Naming
.
optional_args_cname
)
# Locking CyObjects
# Locking CyObjects
# Here we completely ignore the lock mode (nolock/checklock/autolock)
# because the mode is used for direct calls, when the user have the possibility
# to manually lock or let the compiler handle it.
# Here, the user cannot lock manually, so we're taking the lock automatically.
#put_cypclass_op_on_narg_optarg(lambda arg: "Cy_RLOCK" if arg.type.is_const else "Cy_WLOCK",
# reified_function_entry.type, Naming.optional_args_cname, code)
func_type
=
reified_function_entry
.
type
func_type
=
reified_function_entry
.
type
opt_arg_name
=
Naming
.
optional_args_cname
opt_arg_name
=
Naming
.
optional_args_cname
trylock_result
=
"trylock_result"
trylock_result
=
"trylock_result"
...
...
Cython/Compiler/Nodes.py
View file @
a80ce036
...
@@ -1559,7 +1559,6 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
...
@@ -1559,7 +1559,6 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
# templates [(string, bool)] or None
# templates [(string, bool)] or None
# decorators [DecoratorNode] or None
# decorators [DecoratorNode] or None
# cypclass boolean
# cypclass boolean
# lock_mode 'nolock', 'checklock', 'autolock', or None
# activable boolean
# activable boolean
decorators
=
None
decorators
=
None
...
@@ -1584,7 +1583,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
...
@@ -1584,7 +1583,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
self
.
entry
=
env
.
declare_cpp_class
(
self
.
entry
=
env
.
declare_cpp_class
(
self
.
name
,
None
,
self
.
pos
,
self
.
cname
,
self
.
name
,
None
,
self
.
pos
,
self
.
cname
,
base_classes
=
[],
visibility
=
self
.
visibility
,
templates
=
template_types
,
base_classes
=
[],
visibility
=
self
.
visibility
,
templates
=
template_types
,
cypclass
=
self
.
cypclass
,
lock_mode
=
self
.
lock_mode
,
activable
=
self
.
activable
)
cypclass
=
self
.
cypclass
,
activable
=
self
.
activable
)
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
if
self
.
templates
is
None
:
if
self
.
templates
is
None
:
...
@@ -1642,7 +1641,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
...
@@ -1642,7 +1641,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
self
.
entry
=
env
.
declare_cpp_class
(
self
.
entry
=
env
.
declare_cpp_class
(
self
.
name
,
scope
,
self
.
pos
,
self
.
name
,
scope
,
self
.
pos
,
self
.
cname
,
base_class_types
,
visibility
=
self
.
visibility
,
templates
=
template_types
,
self
.
cname
,
base_class_types
,
visibility
=
self
.
visibility
,
templates
=
template_types
,
cypclass
=
self
.
cypclass
,
lock_mode
=
self
.
lock_mode
,
activable
=
self
.
activable
)
cypclass
=
self
.
cypclass
,
activable
=
self
.
activable
)
if
self
.
entry
is
None
:
if
self
.
entry
is
None
:
return
return
self
.
entry
.
is_cpp_class
=
1
self
.
entry
.
is_cpp_class
=
1
...
@@ -8615,8 +8614,11 @@ class LockCypclassNode(StatNode):
...
@@ -8615,8 +8614,11 @@ class LockCypclassNode(StatNode):
self
.
obj
.
analyse_declarations
(
env
)
self
.
obj
.
analyse_declarations
(
env
)
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
self
.
obj
=
self
.
obj
.
analyse_types
(
env
)
self
.
obj
=
obj
=
self
.
obj
.
analyse_types
(
env
)
self
.
body
=
self
.
body
.
analyse_expressions
(
env
)
self
.
body
=
self
.
body
.
analyse_expressions
(
env
)
if
not
obj
.
type
.
is_cyp_class
:
error
(
obj
.
pos
,
"Locking non-cypclass reference"
)
return
self
return
self
return
self
def
generate_execution_code
(
self
,
code
):
def
generate_execution_code
(
self
,
code
):
...
...
Cython/Compiler/Parsing.py
View file @
a80ce036
...
@@ -2544,7 +2544,7 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
...
@@ -2544,7 +2544,7 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
base_type
=
base_type
,
is_const
=
is_const
,
is_volatile
=
is_volatile
)
base_type
=
base_type
,
is_const
=
is_const
,
is_volatile
=
is_volatile
)
# Handle cypclass qualifiers
# Handle cypclass qualifiers
if
s
.
sy
==
'IDENT'
and
s
.
systring
in
(
'active'
,
'iso'
):
if
s
.
sy
==
'IDENT'
and
s
.
systring
in
(
'active'
,
'iso'
,
'locked'
):
qualifier
=
s
.
systring
qualifier
=
s
.
systring
s
.
next
()
s
.
next
()
base_type
=
p_c_base_type
(
s
,
self_flag
=
self_flag
,
nonempty
=
nonempty
,
templates
=
templates
)
base_type
=
p_c_base_type
(
s
,
self_flag
=
self_flag
,
nonempty
=
nonempty
,
templates
=
templates
)
...
@@ -3864,10 +3864,8 @@ def p_cpp_class_definition(s, pos, ctx):
...
@@ -3864,10 +3864,8 @@ def p_cpp_class_definition(s, pos, ctx):
if
s
.
sy
==
'['
:
if
s
.
sy
==
'['
:
error
(
s
.
position
(),
"Name options not allowed for C++ class"
)
error
(
s
.
position
(),
"Name options not allowed for C++ class"
)
nogil
=
p_nogil
(
s
)
or
cypclass
nogil
=
p_nogil
(
s
)
or
cypclass
lock_mode
=
None
activable
=
False
activable
=
False
if
cypclass
:
if
cypclass
:
lock_mode
=
p_cypclass_lock_mode
(
s
)
activable
=
p_cypclass_activable
(
s
)
activable
=
p_cypclass_activable
(
s
)
if
s
.
sy
==
':'
:
if
s
.
sy
==
':'
:
s
.
next
()
s
.
next
()
...
@@ -3897,7 +3895,7 @@ def p_cpp_class_definition(s, pos, ctx):
...
@@ -3897,7 +3895,7 @@ def p_cpp_class_definition(s, pos, ctx):
visibility
=
ctx
.
visibility
,
visibility
=
ctx
.
visibility
,
in_pxd
=
ctx
.
level
==
'module_pxd'
,
in_pxd
=
ctx
.
level
==
'module_pxd'
,
attributes
=
attributes
,
attributes
=
attributes
,
templates
=
templates
,
cypclass
=
cypclass
,
lock_mode
=
lock_mode
,
activable
=
activable
)
templates
=
templates
,
cypclass
=
cypclass
,
activable
=
activable
)
def
p_cpp_class_attribute
(
s
,
ctx
):
def
p_cpp_class_attribute
(
s
,
ctx
):
decorators
=
None
decorators
=
None
...
@@ -3923,14 +3921,6 @@ def p_cpp_class_attribute(s, ctx):
...
@@ -3923,14 +3921,6 @@ def p_cpp_class_attribute(s, ctx):
node
.
decorators
=
decorators
node
.
decorators
=
decorators
return
node
return
node
def
p_cypclass_lock_mode
(
s
):
if
s
.
sy
==
'IDENT'
and
s
.
systring
in
(
'nolock'
,
'checklock'
,
'autolock'
):
mode
=
s
.
systring
s
.
next
()
return
mode
else
:
return
None
def
p_cypclass_activable
(
s
):
def
p_cypclass_activable
(
s
):
if
s
.
sy
==
'IDENT'
and
s
.
systring
==
'activable'
:
if
s
.
sy
==
'IDENT'
and
s
.
systring
==
'activable'
:
s
.
next
()
s
.
next
()
...
...
Cython/Compiler/PyrexTypes.py
View file @
a80ce036
...
@@ -4243,7 +4243,7 @@ class CppClassType(CType):
...
@@ -4243,7 +4243,7 @@ class CppClassType(CType):
CppClassType
(
self
.
name
,
None
,
self
.
cname
,
[],
template_values
,
template_type
=
self
)
\
CppClassType
(
self
.
name
,
None
,
self
.
cname
,
[],
template_values
,
template_type
=
self
)
\
if
not
self
.
is_cyp_class
else
\
if
not
self
.
is_cyp_class
else
\
CypClassType
(
self
.
name
,
None
,
self
.
cname
,
[],
template_values
,
template_type
=
self
,
CypClassType
(
self
.
name
,
None
,
self
.
cname
,
[],
template_values
,
template_type
=
self
,
lock_mode
=
self
.
lock_mode
,
activable
=
self
.
activable
)
activable
=
self
.
activable
)
# Need to do these *after* self.specializations[key] is set
# Need to do these *after* self.specializations[key] is set
# to avoid infinite recursion on circular references.
# to avoid infinite recursion on circular references.
specialized
.
base_classes
=
[
b
.
specialize
(
values
)
for
b
in
self
.
base_classes
]
specialized
.
base_classes
=
[
b
.
specialize
(
values
)
for
b
in
self
.
base_classes
]
...
@@ -4538,7 +4538,6 @@ def compute_mro_generic(cls):
...
@@ -4538,7 +4538,6 @@ def compute_mro_generic(cls):
return
mro_C3_merge
(
inputs
)
return
mro_C3_merge
(
inputs
)
class
CypClassType
(
CppClassType
):
class
CypClassType
(
CppClassType
):
# lock_mode string (tri-state: "nolock"/"checklock"/"autolock")
# _mro [CppClassType] or None the Method Resolution Order of this cypclass according to Python
# _mro [CppClassType] or None the Method Resolution Order of this cypclass according to Python
# support_wrapper boolean whether this cypclass will be wrapped
# support_wrapper boolean whether this cypclass will be wrapped
# wrapper_type PyExtensionType or None the type of the cclass wrapper
# wrapper_type PyExtensionType or None the type of the cclass wrapper
...
@@ -4547,9 +4546,8 @@ class CypClassType(CppClassType):
...
@@ -4547,9 +4546,8 @@ class CypClassType(CppClassType):
to_py_function
=
None
to_py_function
=
None
from_py_function
=
None
from_py_function
=
None
def
__init__
(
self
,
name
,
scope
,
cname
,
base_classes
,
templates
=
None
,
template_type
=
None
,
nogil
=
0
,
lock_mode
=
None
,
activable
=
False
):
def
__init__
(
self
,
name
,
scope
,
cname
,
base_classes
,
templates
=
None
,
template_type
=
None
,
nogil
=
0
,
activable
=
False
):
CppClassType
.
__init__
(
self
,
name
,
scope
,
cname
,
base_classes
,
templates
,
template_type
,
nogil
)
CppClassType
.
__init__
(
self
,
name
,
scope
,
cname
,
base_classes
,
templates
,
template_type
,
nogil
)
self
.
lock_mode
=
lock_mode
if
lock_mode
else
"autolock"
self
.
activable
=
activable
self
.
activable
=
activable
self
.
_mro
=
None
self
.
_mro
=
None
self
.
support_wrapper
=
False
self
.
support_wrapper
=
False
...
@@ -4817,6 +4815,7 @@ class QualifiedCypclassType(BaseType):
...
@@ -4817,6 +4815,7 @@ class QualifiedCypclassType(BaseType):
'iso'
:
(
'iso~'
,),
'iso'
:
(
'iso~'
,),
'iso~'
:
(),
'iso~'
:
(),
'iso&'
:
(
'iso~'
,),
'iso&'
:
(
'iso~'
,),
'locked'
:
(
'locked'
,
'iso~'
),
}
}
def
__init__
(
self
,
base_type
,
qualifier
):
def
__init__
(
self
,
base_type
,
qualifier
):
...
...
Cython/Compiler/Symtab.py
View file @
a80ce036
...
@@ -781,7 +781,7 @@ class Scope(object):
...
@@ -781,7 +781,7 @@ class Scope(object):
def
declare_cpp_class
(
self
,
name
,
scope
,
def
declare_cpp_class
(
self
,
name
,
scope
,
pos
,
cname
=
None
,
base_classes
=
(),
pos
,
cname
=
None
,
base_classes
=
(),
visibility
=
'extern'
,
templates
=
None
,
cypclass
=
0
,
lock_mode
=
None
,
activable
=
False
):
visibility
=
'extern'
,
templates
=
None
,
cypclass
=
0
,
activable
=
False
):
if
cname
is
None
:
if
cname
is
None
:
if
self
.
in_cinclude
or
(
visibility
!=
'private'
):
if
self
.
in_cinclude
or
(
visibility
!=
'private'
):
cname
=
name
cname
=
name
...
@@ -792,7 +792,7 @@ class Scope(object):
...
@@ -792,7 +792,7 @@ class Scope(object):
if
not
entry
:
if
not
entry
:
if
cypclass
:
if
cypclass
:
type
=
PyrexTypes
.
CypClassType
(
type
=
PyrexTypes
.
CypClassType
(
name
,
scope
,
cname
,
base_classes
,
templates
=
templates
,
lock_mode
=
lock_mode
,
activable
=
activable
)
name
,
scope
,
cname
,
base_classes
,
templates
=
templates
,
activable
=
activable
)
else
:
else
:
type
=
PyrexTypes
.
CppClassType
(
type
=
PyrexTypes
.
CppClassType
(
name
,
scope
,
cname
,
base_classes
,
templates
=
templates
)
name
,
scope
,
cname
,
base_classes
,
templates
=
templates
)
...
@@ -3288,6 +3288,8 @@ def qualified_cypclass_scope(base_type_scope, qualifier):
...
@@ -3288,6 +3288,8 @@ def qualified_cypclass_scope(base_type_scope, qualifier):
return
ActiveCypclassScope
(
base_type_scope
)
return
ActiveCypclassScope
(
base_type_scope
)
elif
qualifier
.
startswith
(
'iso'
):
elif
qualifier
.
startswith
(
'iso'
):
return
IsoCypclassScope
(
base_type_scope
)
return
IsoCypclassScope
(
base_type_scope
)
elif
qualifier
==
'locked'
:
return
IsoCypclassScope
(
base_type_scope
,
'locked'
)
else
:
else
:
return
QualifiedCypclassScope
(
base_type_scope
,
qualifier
)
return
QualifiedCypclassScope
(
base_type_scope
,
qualifier
)
...
...
tests/errors/cypclass_lock_error.pyx
deleted
100644 → 0
View file @
a66ffc46
# mode: error
# tag: cpp, cpp11, pthread
# cython: experimental_cpp_class_def=True, language_level=2
cdef
cypclass
A
checklock
:
int
a
int
getter
(
const
self
):
return
self
.
a
void
setter
(
self
,
int
a
):
self
.
a
=
a
cdef
void
take_write_locked
(
A
obj
):
pass
cdef
int
take_read_locked
(
const
A
obj
):
return
3
def
incorrect_locks
():
obj
=
A
()
obj
.
a
=
3
obj
.
getter
()
with
rlocked
obj
:
obj
.
setter
(
42
)
take_write_locked
(
obj
)
obj
.
a
take_read_locked
(
obj
)
cdef
A
global_cyobject
cdef
void
global_lock_taking
():
with
wlocked
global_cyobject
:
global_cyobject
.
setter
(
global_cyobject
.
getter
()
+
1
)
_ERRORS
=
u"""
20:4: Reference 'obj' is not correctly locked in this expression (write lock required)
21:4: Reference 'obj' is not correctly locked in this expression (read lock required)
23:8: Reference 'obj' is not correctly locked in this expression (write lock required)
24:26: Reference 'obj' is not correctly locked in this expression (write lock required)
25:4: Reference 'obj' is not correctly locked in this expression (read lock required)
26:21: Reference 'obj' is not correctly locked in this expression (read lock required)
32:17: Can only lock local variables or arguments
"""
tests/run/cypclass_acthon.pyx
View file @
a80ce036
...
@@ -14,7 +14,7 @@ cdef extern from "<semaphore.h>" nogil:
...
@@ -14,7 +14,7 @@ cdef extern from "<semaphore.h>" nogil:
int
sem_destroy
(
sem_t
*
sem
)
int
sem_destroy
(
sem_t
*
sem
)
cdef
cypclass
BasicQueue
(
ActhonQueueInterface
)
checklock
:
cdef
cypclass
BasicQueue
(
ActhonQueueInterface
):
message_queue_t
*
_queue
message_queue_t
*
_queue
__init__
(
self
):
__init__
(
self
):
...
@@ -53,7 +53,7 @@ cdef cypclass BasicQueue(ActhonQueueInterface) checklock:
...
@@ -53,7 +53,7 @@ cdef cypclass BasicQueue(ActhonQueueInterface) checklock:
# Don't forget to incref to avoid premature deallocation
# Don't forget to incref to avoid premature deallocation
return
one_message_processed
return
one_message_processed
cdef
cypclass
NoneResult
(
ActhonResultInterface
)
checklock
:
cdef
cypclass
NoneResult
(
ActhonResultInterface
):
void
pushVoidStarResult
(
self
,
void
*
result
):
void
pushVoidStarResult
(
self
,
void
*
result
):
pass
pass
void
pushIntResult
(
self
,
int
result
):
void
pushIntResult
(
self
,
int
result
):
...
@@ -63,7 +63,7 @@ cdef cypclass NoneResult(ActhonResultInterface) checklock:
...
@@ -63,7 +63,7 @@ cdef cypclass NoneResult(ActhonResultInterface) checklock:
int
getIntResult
(
const
self
):
int
getIntResult
(
const
self
):
return
0
return
0
cdef
cypclass
WaitResult
(
ActhonResultInterface
)
checklock
:
cdef
cypclass
WaitResult
(
ActhonResultInterface
):
union
result_t
:
union
result_t
:
int
int_val
int
int_val
void
*
ptr
void
*
ptr
...
@@ -104,7 +104,7 @@ cdef cypclass WaitResult(ActhonResultInterface) checklock:
...
@@ -104,7 +104,7 @@ cdef cypclass WaitResult(ActhonResultInterface) checklock:
res
=
self
.
_getRawResult
()
res
=
self
.
_getRawResult
()
return
res
.
int_val
return
res
.
int_val
cdef
cypclass
ActivityCounterSync
(
ActhonSyncInterface
)
checklock
:
cdef
cypclass
ActivityCounterSync
(
ActhonSyncInterface
):
int
count
int
count
ActivityCounterSync
previous_sync
ActivityCounterSync
previous_sync
...
@@ -129,7 +129,7 @@ cdef cypclass ActivityCounterSync(ActhonSyncInterface) checklock:
...
@@ -129,7 +129,7 @@ cdef cypclass ActivityCounterSync(ActhonSyncInterface) checklock:
res
=
prev_sync
.
isCompleted
()
res
=
prev_sync
.
isCompleted
()
return
res
return
res
cdef
cypclass
A
checklock
activable
:
cdef
cypclass
A
activable
:
int
a
int
a
__init__
(
self
):
__init__
(
self
):
self
.
a
=
0
self
.
a
=
0
...
@@ -148,19 +148,17 @@ def test_acthon_chain(n):
...
@@ -148,19 +148,17 @@ def test_acthon_chain(n):
cdef
ActhonResultInterface
res
cdef
ActhonResultInterface
res
cdef
ActhonQueueInterface
queue
cdef
ActhonQueueInterface
queue
sync1
=
ActivityCounterSync
()
sync1
=
ActivityCounterSync
()
with
wlocked
sync1
:
after_sync1
=
ActivityCounterSync
(
sync1
)
after_sync1
=
ActivityCounterSync
(
sync1
)
obj
=
A
()
obj
=
A
()
with
wlocked
obj
:
obj_actor
=
activate
(
obj
)
obj_actor
=
activate
(
obj
)
with
wlocked
obj_actor
,
wlocked
sync1
,
wlocked
after_sync1
:
# Pushing things in the queue
# Pushing things in the queue
obj_actor
.
setter
(
sync1
,
n
)
obj_actor
.
setter
(
sync1
,
n
)
res
=
obj_actor
.
getter
(
after_sync1
)
res
=
obj_actor
.
getter
(
after_sync1
)
# Processing the queue
# Processing the queue
with
rlocked
obj
:
queue
=
obj
.
_active_queue_class
queue
=
obj
.
_active_queue_class
with
wlocked
queue
:
while
not
queue
.
is_empty
():
while
not
queue
.
is_empty
():
queue
.
activate
()
queue
.
activate
()
print
<
int
>
res
print
<
int
>
res
tests/run/cypclass_exception_refcount.pyx
View file @
a80ce036
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
# tag: cpp, cpp11
# tag: cpp, cpp11
# cython: experimental_cpp_class_def=True, language_level=2
# cython: experimental_cpp_class_def=True, language_level=2
cdef
cypclass
Refcounted
nolock
:
cdef
cypclass
Refcounted
:
pass
pass
cdef
int
raises
(
Refcounted
r
)
except
0
:
cdef
int
raises
(
Refcounted
r
)
except
0
:
...
...
tests/run/cypclass_inplace_operator_inference.pyx
View file @
a80ce036
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
# tag: cpp, cpp11
# tag: cpp, cpp11
# cython: experimental_cpp_class_def=True, language_level=2
# cython: experimental_cpp_class_def=True, language_level=2
cdef
cypclass
A
nolock
:
cdef
cypclass
A
:
int
val
int
val
__init__
(
self
,
int
a
):
__init__
(
self
,
int
a
):
self
.
val
=
a
self
.
val
=
a
...
@@ -10,7 +10,7 @@ cdef cypclass A nolock:
...
@@ -10,7 +10,7 @@ cdef cypclass A nolock:
A
__iadd__
(
self
,
A
other
):
A
__iadd__
(
self
,
A
other
):
self
.
val
+=
(
other
.
val
+
1
)
self
.
val
+=
(
other
.
val
+
1
)
cdef
cypclass
B
(
A
)
nolock
:
cdef
cypclass
B
(
A
):
B
__iadd__
(
self
,
A
other
):
B
__iadd__
(
self
,
A
other
):
self
.
val
+=
(
other
.
val
+
10
)
self
.
val
+=
(
other
.
val
+
10
)
...
...
tests/run/cypclass_lock.pyx
deleted
100644 → 0
View file @
a66ffc46
# mode: run
# tag: cpp, cpp11, pthread
# cython: experimental_cpp_class_def=True, language_level=2
cdef
cypclass
A
checklock
:
int
a
__init__
(
self
):
self
.
a
=
0
int
getter
(
const
self
):
return
self
.
a
void
setter
(
self
,
int
a
):
self
.
a
=
a
def
test_basic_locking
():
"""
>>> test_basic_locking()
0
"""
obj
=
A
()
with
rlocked
obj
:
print
obj
.
getter
()
cdef
argument_recursivity
(
A
obj
,
int
arg
):
if
arg
>
0
:
obj
.
setter
(
obj
.
getter
()
+
1
)
argument_recursivity
(
obj
,
arg
-
1
)
def
test_argument_recursivity
(
n
):
"""
>>> test_argument_recursivity(42)
42
"""
obj
=
A
()
with
wlocked
obj
:
argument_recursivity
(
obj
,
n
)
print
obj
.
a
cdef
cypclass
Container
:
A
object
__init__
(
self
):
self
.
object
=
A
()
def
test_lock_traversal
(
n
):
"""
>>> test_lock_traversal(42)
42
"""
container
=
Container
()
with
rlocked
container
:
contained
=
container
.
object
with
wlocked
contained
:
argument_recursivity
(
contained
,
n
)
print
contained
.
getter
()
tests/run/cypclass_nested_classes.pyx
View file @
a80ce036
...
@@ -2,10 +2,10 @@
...
@@ -2,10 +2,10 @@
# tag: cpp, cpp11
# tag: cpp, cpp11
# cython: experimental_cpp_class_def=True, language_level=2
# cython: experimental_cpp_class_def=True, language_level=2
cdef
cypclass
A
nolock
:
cdef
cypclass
A
:
int
a
int
a
cypclass
B
nolock
:
cypclass
B
:
int
b
int
b
__init__
(
self
,
int
b
):
__init__
(
self
,
int
b
):
self
.
b
=
b
self
.
b
=
b
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment