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 ...@@ -32,11 +32,14 @@ from golang import go, chan, select, default, nilchan
from golang import _sync # avoid cycle: context -> sync -> context from golang import _sync # avoid cycle: context -> sync -> context
from golang import time from golang import time
from cython cimport final
# Context is the interface that every context must implement. # Context is the interface that every context must implement.
# #
# A context carries deadline, cancellation signal and immutable context-local # A context carries deadline, cancellation signal and immutable context-local
# key -> value dict. # key -> value dict.
class Context(object): cdef class Context:
# deadline() returns context deadline or None, if there is no deadline. # deadline() returns context deadline or None, if there is no deadline.
def deadline(ctx): # -> time | None def deadline(ctx): # -> time | None
raise NotImplementedError() raise NotImplementedError()
...@@ -133,7 +136,8 @@ def merge(parent1, parent2): # -> ctx, cancel ...@@ -133,7 +136,8 @@ def merge(parent1, parent2): # -> ctx, cancel
# -------- # --------
# _Background implements root context that is never canceled. # _Background implements root context that is never canceled.
class _Background(object): @final
cdef class _Background:
def done(bg): def done(bg):
return _nilchanZ return _nilchanZ
...@@ -150,14 +154,21 @@ _background = _Background() ...@@ -150,14 +154,21 @@ _background = _Background()
_nilchanZ = chan.nil('C.structZ') _nilchanZ = chan.nil('C.structZ')
# _BaseCtx is the common base for Contexts implemented in this package. # _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): def __init__(ctx, done, *parentv):
# parents of this context - either _BaseCtx* or generic Context.
# does not change after setup.
ctx._parentv = parentv ctx._parentv = parentv
ctx._mu = _sync.PyMutex() ctx._mu = _sync.PyMutex()
ctx._children = set() # children of this context - we propagate cancel there (all _BaseCtx) ctx._children = set()
ctx._err = None ctx._err = None
# chan: if context can be canceled on its own # chan: if context can be canceled on its own
...@@ -218,9 +229,10 @@ class _BaseCtx(object): ...@@ -218,9 +229,10 @@ class _BaseCtx(object):
if parent is cancelFrom: if parent is cancelFrom:
continue continue
if isinstance(parent, _BaseCtx): if isinstance(parent, _BaseCtx):
with parent._mu: _parent = <_BaseCtx>parent
if ctx in parent._children: with _parent._mu:
parent._children.remove(ctx) if ctx in _parent._children:
_parent._children.remove(ctx)
# propagate cancel to children # propagate cancel to children
for child in children: for child in children:
...@@ -240,11 +252,12 @@ class _BaseCtx(object): ...@@ -240,11 +252,12 @@ class _BaseCtx(object):
# parent is cancellable - glue to propagate cancel from it to us # parent is cancellable - glue to propagate cancel from it to us
if isinstance(parent, _BaseCtx): if isinstance(parent, _BaseCtx):
with parent._mu: _parent = <_BaseCtx>parent
if parent._err is not None: with _parent._mu:
ctx._cancel(parent._err) if _parent._err is not None:
ctx._cancel(_parent._err)
else: else:
parent._children.add(ctx) _parent._children.add(ctx)
else: else:
if _ready(pdone): if _ready(pdone):
ctx._cancel(parent.err()) ctx._cancel(parent.err())
...@@ -267,19 +280,20 @@ class _BaseCtx(object): ...@@ -267,19 +280,20 @@ class _BaseCtx(object):
# _CancelCtx is context that can be canceled. # _CancelCtx is context that can be canceled.
class _CancelCtx(_BaseCtx): cdef class _CancelCtx(_BaseCtx):
def __init__(ctx, *parentv): def __init__(ctx, *parentv):
super(_CancelCtx, ctx).__init__(chan(dtype='C.structZ'), *parentv) super(_CancelCtx, ctx).__init__(chan(dtype='C.structZ'), *parentv)
# _ValueCtx is context that carries key -> value. # _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): def __init__(ctx, kv, parent):
super(_ValueCtx, ctx).__init__(None, 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 ctx._kv = kv
def value(ctx, key): def value(ctx, key):
...@@ -290,7 +304,10 @@ class _ValueCtx(_BaseCtx): ...@@ -290,7 +304,10 @@ class _ValueCtx(_BaseCtx):
# _TimeoutCtx is context that is canceled on timeout. # _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): def __init__(ctx, timeout, deadline, parent):
super(_TimeoutCtx, ctx).__init__(parent) super(_TimeoutCtx, ctx).__init__(parent)
assert timeout > 0 assert timeout > 0
...@@ -317,3 +334,9 @@ def _ready(ch): ...@@ -317,3 +334,9 @@ def _ready(ch):
return True return True
if _ == 1: if _ == 1:
return False return False
# ---- for tests ----
def _tctxchildren(_BaseCtx ctx): # -> ctx._children
return ctx._children
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
from __future__ import print_function, absolute_import from __future__ import print_function, absolute_import
from golang import context, _context, time, nilchan 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 from golang.time_test import dt
# assertCtx asserts on state of _BaseCtx* # assertCtx asserts on state of _BaseCtx*
...@@ -30,7 +30,7 @@ def assertCtx(ctx, children, deadline=None, err=None, done=False): ...@@ -30,7 +30,7 @@ def assertCtx(ctx, children, deadline=None, err=None, done=False):
assert ctx.deadline() == deadline assert ctx.deadline() == deadline
assert ctx.err() is err assert ctx.err() is err
assert ready(ctx.done()) == done assert ready(ctx.done()) == done
assert ctx._children == children assert tctxchildren(ctx) == children
Z = set() # empty set Z = set() # empty set
C = context.canceled 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