moonraker: don't allow a unix socket to open while closing
Hold the closed mutex in the "connect()" method. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
31dd758d52
commit
3f7cc53baa
|
@ -707,35 +707,36 @@ class KlippyConnection:
|
||||||
event_loop: EventLoop
|
event_loop: EventLoop
|
||||||
) -> None:
|
) -> None:
|
||||||
self.writer: Optional[asyncio.StreamWriter] = None
|
self.writer: Optional[asyncio.StreamWriter] = None
|
||||||
self.closed: bool = True
|
self.connection_mutex: asyncio.Lock = asyncio.Lock()
|
||||||
self.close_mutex: asyncio.Lock = asyncio.Lock()
|
|
||||||
self.on_recd = on_recd
|
self.on_recd = on_recd
|
||||||
self.on_close = on_close
|
self.on_close = on_close
|
||||||
self.event_loop = event_loop
|
self.event_loop = event_loop
|
||||||
self.log_no_access = True
|
self.log_no_access = True
|
||||||
|
|
||||||
async def connect(self, address: str) -> bool:
|
async def connect(self, address: str) -> bool:
|
||||||
if not os.path.exists(address):
|
if self.is_connected():
|
||||||
return False
|
await self.close()
|
||||||
if not os.access(address, os.R_OK | os.W_OK):
|
async with self.connection_mutex:
|
||||||
if self.log_no_access:
|
if not os.path.exists(address):
|
||||||
user = getpass.getuser()
|
return False
|
||||||
logging.info(
|
if not os.access(address, os.R_OK | os.W_OK):
|
||||||
f"Cannot connect to Klippy, Linux user '{user}' lacks "
|
if self.log_no_access:
|
||||||
f"permission to open Unix Domain Socket: {address}")
|
user = getpass.getuser()
|
||||||
self.log_no_access = False
|
logging.info(
|
||||||
return False
|
f"Cannot connect to Klippy, Linux user '{user}' lacks "
|
||||||
self.log_no_access = True
|
f"permission to open Unix Domain Socket: {address}")
|
||||||
try:
|
self.log_no_access = False
|
||||||
reader, writer = await asyncio.open_unix_connection(
|
return False
|
||||||
address, limit=UNIX_BUFFER_LIMIT)
|
self.log_no_access = True
|
||||||
except Exception:
|
try:
|
||||||
return False
|
reader, writer = await asyncio.open_unix_connection(
|
||||||
logging.info("Klippy Connection Established")
|
address, limit=UNIX_BUFFER_LIMIT)
|
||||||
self.closed = False
|
except Exception:
|
||||||
self.writer = writer
|
return False
|
||||||
self.event_loop.register_callback(self._read_stream, reader)
|
logging.info("Klippy Connection Established")
|
||||||
return True
|
self.writer = writer
|
||||||
|
self.event_loop.register_callback(self._read_stream, reader)
|
||||||
|
return True
|
||||||
|
|
||||||
async def _read_stream(self, reader: asyncio.StreamReader) -> None:
|
async def _read_stream(self, reader: asyncio.StreamReader) -> None:
|
||||||
errors_remaining: int = 10
|
errors_remaining: int = 10
|
||||||
|
@ -770,21 +771,23 @@ class KlippyConnection:
|
||||||
await self.close()
|
await self.close()
|
||||||
|
|
||||||
def is_connected(self) -> bool:
|
def is_connected(self) -> bool:
|
||||||
return not self.closed
|
return self.writer is not None
|
||||||
|
|
||||||
async def close(self) -> None:
|
async def close(self) -> None:
|
||||||
async with self.close_mutex:
|
if (
|
||||||
if self.writer is not None:
|
self.connection_mutex.locked() or
|
||||||
try:
|
self.writer is None
|
||||||
self.writer.close()
|
):
|
||||||
await self.writer.wait_closed()
|
return
|
||||||
except Exception:
|
async with self.connection_mutex:
|
||||||
logging.exception("Error closing Klippy Unix Socket")
|
try:
|
||||||
self.writer = None
|
self.writer.close()
|
||||||
if not self.closed:
|
await self.writer.wait_closed()
|
||||||
self.closed = True
|
except Exception:
|
||||||
self.on_close()
|
logging.exception("Error closing Klippy Unix Socket")
|
||||||
self.closing = False
|
self.writer = None
|
||||||
|
self.on_close()
|
||||||
|
|
||||||
|
|
||||||
# Basic WebRequest class, easily converted to dict for json encoding
|
# Basic WebRequest class, easily converted to dict for json encoding
|
||||||
class BaseRequest:
|
class BaseRequest:
|
||||||
|
|
Loading…
Reference in New Issue