Commit 223d7950 authored by Kirill Smelkov's avatar Kirill Smelkov

context: Turn all classes into -> cdef classes

Similarly to 0e838833 (time: Turn Ticker and Timer into cdef classes)
rework all classes in context package to be cdef classes:

- cdef their attributes (else accessing any of them raises
  AttributeError). But don't change any of them to be used in cimport
  mode yet - this will be done later as separate steps.
parent cc7069e0
......@@ -32,11 +32,14 @@ from golang import go, chan, select, default, nilchan
from golang import _sync # avoid cycle: context -> sync -> context
from golang import time
from cython cimport final
# Context is the interface that every context must implement.
#
# A context carries deadline, cancellation signal and immutable context-local
# key -> value dict.
class Context(object):
cdef class Context:
# deadline() returns context deadline or None, if there is no deadline.
def deadline(ctx): # -> time | None
raise NotImplementedError()
......@@ -133,7 +136,8 @@ def merge(parent1, parent2): # -> ctx, cancel
# --------
# _Background implements root context that is never canceled.
class _Background(object):
@final
cdef class _Background:
def done(bg):
return _nilchanZ
......@@ -150,14 +154,21 @@ _background = _Background()
_nilchanZ = chan.nil('C.structZ')
# _BaseCtx is the common base for Contexts implemented in this package.
class _BaseCtx(object):
cdef class _BaseCtx:
# parents of this context - either _BaseCtx* or generic Context.
# does not change after setup.
cdef tuple _parentv
cdef object _mu # sync.PyMutex
cdef set _children # children of this context - we propagate cancel there (all _BaseCtx)
cdef object _err
cdef object _done # pychan | None
def __init__(ctx, done, *parentv):
# parents of this context - either _BaseCtx* or generic Context.
# does not change after setup.
ctx._parentv = parentv
ctx._mu = _sync.PyMutex()
ctx._children = set() # children of this context - we propagate cancel there (all _BaseCtx)
ctx._children = set()
ctx._err = None
# chan: if context can be canceled on its own
......@@ -218,9 +229,10 @@ class _BaseCtx(object):
if parent is cancelFrom:
continue
if isinstance(parent, _BaseCtx):
with parent._mu:
if ctx in parent._children:
parent._children.remove(ctx)
_parent = <_BaseCtx>parent
with _parent._mu:
if ctx in _parent._children:
_parent._children.remove(ctx)
# propagate cancel to children
for child in children:
......@@ -240,11 +252,12 @@ class _BaseCtx(object):
# parent is cancellable - glue to propagate cancel from it to us
if isinstance(parent, _BaseCtx):
with parent._mu:
if parent._err is not None:
ctx._cancel(parent._err)
_parent = <_BaseCtx>parent
with _parent._mu:
if _parent._err is not None:
ctx._cancel(_parent._err)
else:
parent._children.add(ctx)
_parent._children.add(ctx)
else:
if _ready(pdone):
ctx._cancel(parent.err())
......@@ -267,19 +280,20 @@ class _BaseCtx(object):
# _CancelCtx is context that can be canceled.
class _CancelCtx(_BaseCtx):
cdef class _CancelCtx(_BaseCtx):
def __init__(ctx, *parentv):
super(_CancelCtx, ctx).__init__(chan(dtype='C.structZ'), *parentv)
# _ValueCtx is context that carries key -> value.
class _ValueCtx(_BaseCtx):
cdef class _ValueCtx(_BaseCtx):
# {} (key, value) specific to this context.
# the rest of the keys are inherited from parents.
# does not change after setup.
cdef dict _kv
def __init__(ctx, kv, parent):
super(_ValueCtx, ctx).__init__(None, parent)
# {} (key, value) specific to this context.
# the rest of the keys are inherited from parents.
# does not change after setup.
ctx._kv = kv
def value(ctx, key):
......@@ -290,7 +304,10 @@ class _ValueCtx(_BaseCtx):
# _TimeoutCtx is context that is canceled on timeout.
class _TimeoutCtx(_CancelCtx):
cdef class _TimeoutCtx(_CancelCtx):
cdef double _deadline
cdef object _timer # time.Timer
def __init__(ctx, timeout, deadline, parent):
super(_TimeoutCtx, ctx).__init__(parent)
assert timeout > 0
......@@ -317,3 +334,9 @@ def _ready(ch):
return True
if _ == 1:
return False
# ---- for tests ----
def _tctxchildren(_BaseCtx ctx): # -> ctx._children
return ctx._children
......@@ -21,7 +21,7 @@
from __future__ import print_function, absolute_import
from golang import context, _context, time, nilchan
from golang._context import _ready as ready
from golang._context import _tctxchildren as tctxchildren, _ready as ready
from golang.time_test import dt
# assertCtx asserts on state of _BaseCtx*
......@@ -30,7 +30,7 @@ def assertCtx(ctx, children, deadline=None, err=None, done=False):
assert ctx.deadline() == deadline
assert ctx.err() is err
assert ready(ctx.done()) == done
assert ctx._children == children
assert tctxchildren(ctx) == children
Z = set() # empty set
C = context.canceled
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment