|
11 | 11 | """ |
12 | 12 |
|
13 | 13 | import logging |
| 14 | +import os |
| 15 | +import tempfile |
14 | 16 | from collections import deque |
15 | 17 |
|
16 | 18 | from can import Message, CanError, BusABC |
|
27 | 29 | ics = None |
28 | 30 |
|
29 | 31 |
|
| 32 | +try: |
| 33 | + from filelock import FileLock |
| 34 | +except ImportError as ie: |
| 35 | + |
| 36 | + logger.warning( |
| 37 | + "Using ICS NeoVi can backend without the " |
| 38 | + "filelock module installed may cause some issues!: %s", |
| 39 | + ie, |
| 40 | + ) |
| 41 | + |
| 42 | + class FileLock: |
| 43 | + """Dummy file lock that does not actually do anything""" |
| 44 | + |
| 45 | + def __init__(self, lock_file, timeout=-1): |
| 46 | + self._lock_file = lock_file |
| 47 | + self.timeout = timeout |
| 48 | + |
| 49 | + def __enter__(self): |
| 50 | + return self |
| 51 | + |
| 52 | + def __exit__(self, exc_type, exc_val, exc_tb): |
| 53 | + return None |
| 54 | + |
| 55 | + |
| 56 | +# Use inter-process mutex to prevent concurrent device open. |
| 57 | +# When neoVI server is enabled, there is an issue with concurrent device open. |
| 58 | +open_lock = FileLock(os.path.join(tempfile.gettempdir(), "neovi.lock")) |
| 59 | + |
| 60 | + |
30 | 61 | class ICSApiError(CanError): |
31 | 62 | """ |
32 | 63 | Indicates an error with the ICS API. |
@@ -118,18 +149,28 @@ def __init__(self, channel, can_filters=None, **kwargs): |
118 | 149 | type_filter = kwargs.get('type_filter') |
119 | 150 | serial = kwargs.get('serial') |
120 | 151 | self.dev = self._find_device(type_filter, serial) |
121 | | - ics.open_device(self.dev) |
122 | 152 |
|
123 | | - if 'bitrate' in kwargs: |
124 | | - for channel in self.channels: |
125 | | - ics.set_bit_rate(self.dev, kwargs.get('bitrate'), channel) |
| 153 | + with open_lock: |
| 154 | + ics.open_device(self.dev) |
126 | 155 |
|
127 | | - fd = kwargs.get('fd', False) |
128 | | - if fd: |
129 | | - if 'data_bitrate' in kwargs: |
| 156 | + try: |
| 157 | + if "bitrate" in kwargs: |
130 | 158 | for channel in self.channels: |
131 | | - ics.set_fd_bit_rate( |
132 | | - self.dev, kwargs.get('data_bitrate'), channel) |
| 159 | + ics.set_bit_rate(self.dev, kwargs.get("bitrate"), channel) |
| 160 | + |
| 161 | + if kwargs.get("fd", False): |
| 162 | + if "data_bitrate" in kwargs: |
| 163 | + for channel in self.channels: |
| 164 | + ics.set_fd_bit_rate( |
| 165 | + self.dev, kwargs.get("data_bitrate"), channel |
| 166 | + ) |
| 167 | + except ics.RuntimeError as re: |
| 168 | + logger.error(re) |
| 169 | + err = ICSApiError(*ics.get_last_api_error(self.dev)) |
| 170 | + try: |
| 171 | + self.shutdown() |
| 172 | + finally: |
| 173 | + raise err |
133 | 174 |
|
134 | 175 | self._use_system_timestamp = bool( |
135 | 176 | kwargs.get('use_system_timestamp', False) |
|
0 commit comments