/usr/lib/python3/dist-packages/wormhole/_mailbox.py is in magic-wormhole 0.10.3-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | from __future__ import print_function, absolute_import, unicode_literals
from zope.interface import implementer
from attr import attrs, attrib
from attr.validators import instance_of
from automat import MethodicalMachine
from . import _interfaces
@attrs
@implementer(_interfaces.IMailbox)
class Mailbox(object):
_side = attrib(validator=instance_of(type(u"")))
m = MethodicalMachine()
set_trace = getattr(m, "_setTrace", lambda self, f: None)
def __attrs_post_init__(self):
self._mailbox = None
self._pending_outbound = {}
self._processed = set()
def wire(self, nameplate, rendezvous_connector, ordering, terminator):
self._N = _interfaces.INameplate(nameplate)
self._RC = _interfaces.IRendezvousConnector(rendezvous_connector)
self._O = _interfaces.IOrder(ordering)
self._T = _interfaces.ITerminator(terminator)
# all -A states: not connected
# all -B states: yes connected
# B states serialize as A, so they deserialize as unconnected
# S0: know nothing
@m.state(initial=True)
def S0A(self): pass # pragma: no cover
@m.state()
def S0B(self): pass # pragma: no cover
# S1: mailbox known, not opened
@m.state()
def S1A(self): pass # pragma: no cover
# S2: mailbox known, opened
# We've definitely tried to open the mailbox at least once, but it must
# be re-opened with each connection, because open() is also subscribe()
@m.state()
def S2A(self): pass # pragma: no cover
@m.state()
def S2B(self): pass # pragma: no cover
# S3: closing
@m.state()
def S3A(self): pass # pragma: no cover
@m.state()
def S3B(self): pass # pragma: no cover
# S4: closed. We no longer care whether we're connected or not
#@m.state()
#def S4A(self): pass
#@m.state()
#def S4B(self): pass
@m.state(terminal=True)
def S4(self): pass # pragma: no cover
S4A = S4
S4B = S4
# from Terminator
@m.input()
def close(self, mood): pass
# from Nameplate
@m.input()
def got_mailbox(self, mailbox): pass
# from RendezvousConnector
@m.input()
def connected(self): pass
@m.input()
def lost(self): pass
def rx_message(self, side, phase, body):
assert isinstance(side, type("")), type(side)
assert isinstance(phase, type("")), type(phase)
assert isinstance(body, type(b"")), type(body)
if side == self._side:
self.rx_message_ours(phase, body)
else:
self.rx_message_theirs(side, phase, body)
@m.input()
def rx_message_ours(self, phase, body): pass
@m.input()
def rx_message_theirs(self, side, phase, body): pass
@m.input()
def rx_closed(self): pass
# from Send or Key
@m.input()
def add_message(self, phase, body):
pass
@m.output()
def record_mailbox(self, mailbox):
self._mailbox = mailbox
@m.output()
def RC_tx_open(self):
assert self._mailbox
self._RC.tx_open(self._mailbox)
@m.output()
def queue(self, phase, body):
assert isinstance(phase, type("")), type(phase)
assert isinstance(body, type(b"")), (type(body), phase, body)
self._pending_outbound[phase] = body
@m.output()
def record_mailbox_and_RC_tx_open_and_drain(self, mailbox):
self._mailbox = mailbox
self._RC.tx_open(mailbox)
self._drain()
@m.output()
def drain(self):
self._drain()
def _drain(self):
for phase, body in self._pending_outbound.items():
self._RC.tx_add(phase, body)
@m.output()
def RC_tx_add(self, phase, body):
assert isinstance(phase, type("")), type(phase)
assert isinstance(body, type(b"")), type(body)
self._RC.tx_add(phase, body)
@m.output()
def N_release_and_accept(self, side, phase, body):
self._N.release()
if phase not in self._processed:
self._processed.add(phase)
self._O.got_message(side, phase, body)
@m.output()
def RC_tx_close(self):
assert self._mood
self._RC_tx_close()
def _RC_tx_close(self):
self._RC.tx_close(self._mailbox, self._mood)
@m.output()
def dequeue(self, phase, body):
self._pending_outbound.pop(phase, None)
@m.output()
def record_mood(self, mood):
self._mood = mood
@m.output()
def record_mood_and_RC_tx_close(self, mood):
self._mood = mood
self._RC_tx_close()
@m.output()
def ignore_mood_and_T_mailbox_done(self, mood):
self._T.mailbox_done()
@m.output()
def T_mailbox_done(self):
self._T.mailbox_done()
S0A.upon(connected, enter=S0B, outputs=[])
S0A.upon(got_mailbox, enter=S1A, outputs=[record_mailbox])
S0A.upon(add_message, enter=S0A, outputs=[queue])
S0A.upon(close, enter=S4A, outputs=[ignore_mood_and_T_mailbox_done])
S0B.upon(lost, enter=S0A, outputs=[])
S0B.upon(add_message, enter=S0B, outputs=[queue])
S0B.upon(close, enter=S4B, outputs=[ignore_mood_and_T_mailbox_done])
S0B.upon(got_mailbox, enter=S2B,
outputs=[record_mailbox_and_RC_tx_open_and_drain])
S1A.upon(connected, enter=S2B, outputs=[RC_tx_open, drain])
S1A.upon(add_message, enter=S1A, outputs=[queue])
S1A.upon(close, enter=S4A, outputs=[ignore_mood_and_T_mailbox_done])
S2A.upon(connected, enter=S2B, outputs=[RC_tx_open, drain])
S2A.upon(add_message, enter=S2A, outputs=[queue])
S2A.upon(close, enter=S3A, outputs=[record_mood])
S2B.upon(lost, enter=S2A, outputs=[])
S2B.upon(add_message, enter=S2B, outputs=[queue, RC_tx_add])
S2B.upon(rx_message_theirs, enter=S2B, outputs=[N_release_and_accept])
S2B.upon(rx_message_ours, enter=S2B, outputs=[dequeue])
S2B.upon(close, enter=S3B, outputs=[record_mood_and_RC_tx_close])
S3A.upon(connected, enter=S3B, outputs=[RC_tx_close])
S3B.upon(lost, enter=S3A, outputs=[])
S3B.upon(rx_closed, enter=S4B, outputs=[T_mailbox_done])
S3B.upon(add_message, enter=S3B, outputs=[])
S3B.upon(rx_message_theirs, enter=S3B, outputs=[])
S3B.upon(rx_message_ours, enter=S3B, outputs=[])
S3B.upon(close, enter=S3B, outputs=[])
S4A.upon(connected, enter=S4B, outputs=[])
S4B.upon(lost, enter=S4A, outputs=[])
S4.upon(add_message, enter=S4, outputs=[])
S4.upon(rx_message_theirs, enter=S4, outputs=[])
S4.upon(rx_message_ours, enter=S4, outputs=[])
S4.upon(close, enter=S4, outputs=[])
|