Coverage for /pythoncovmergedfiles/medio/medio/src/paramiko/tests/_loop.py: 64%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Copyright (C) 2003-2009 Robey Pointer <robeypointer@gmail.com>
2#
3# This file is part of paramiko.
4#
5# Paramiko is free software; you can redistribute it and/or modify it under the
6# terms of the GNU Lesser General Public License as published by the Free
7# Software Foundation; either version 2.1 of the License, or (at your option)
8# any later version.
9#
10# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY
11# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13# details.
14#
15# You should have received a copy of the GNU Lesser General Public License
16# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
17# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19import socket
20import threading
22from paramiko.util import asbytes
25class LoopSocket:
26 """
27 A LoopSocket looks like a normal socket, but all data written to it is
28 delivered on the read-end of another LoopSocket, and vice versa. It's
29 like a software "socketpair".
30 """
32 def __init__(self):
33 self.__in_buffer = bytes()
34 self.__lock = threading.Lock()
35 self.__cv = threading.Condition(self.__lock)
36 self.__timeout = None
37 self.__mate = None
38 self._closed = False
40 def close(self):
41 self.__unlink()
42 self._closed = True
43 try:
44 self.__lock.acquire()
45 self.__in_buffer = bytes()
46 finally:
47 self.__lock.release()
49 def send(self, data):
50 data = asbytes(data)
51 if self.__mate is None:
52 # EOF
53 raise EOFError()
54 self.__mate.__feed(data)
55 return len(data)
57 def recv(self, n):
58 self.__lock.acquire()
59 try:
60 if self.__mate is None:
61 # EOF
62 return bytes()
63 if len(self.__in_buffer) == 0:
64 self.__cv.wait(self.__timeout)
65 if len(self.__in_buffer) == 0:
66 raise socket.timeout
67 out = self.__in_buffer[:n]
68 self.__in_buffer = self.__in_buffer[n:]
69 return out
70 finally:
71 self.__lock.release()
73 def settimeout(self, n):
74 self.__timeout = n
76 def link(self, other):
77 self.__mate = other
78 self.__mate.__mate = self
80 def __feed(self, data):
81 self.__lock.acquire()
82 try:
83 self.__in_buffer += data
84 self.__cv.notify_all()
85 finally:
86 self.__lock.release()
88 def __unlink(self):
89 m = None
90 self.__lock.acquire()
91 try:
92 if self.__mate is not None:
93 m = self.__mate
94 self.__mate = None
95 finally:
96 self.__lock.release()
97 if m is not None:
98 m.__unlink()