In my work of porting canopen to asyncio, I stubled across that canopen contains a lot of unprotected thread crossings. By and large all callbacks coming from can through Network.notify() run in another thread. This means that all subscribed callbacks must protect any class members access, otherwise interesting results may arise. Many callback handlers have synchronization mechanisms, but there a still quite a few that does not.
emcy.py:EcmyConsumer.on_emcy() Callbacks are not protected
network.py:NodeScanner.on_message_received() self.nodes is not protected
nmt.py:NmtBase.on_command() self._state is update and not protected
nmt.py:NmtSlave.on_command() self.update_heartbeat() is called which alters state
profiles/p402.py:BaseNode402.on_TPDOs_update_callback() self.tpdo_values[] updated from thread
sdo/server.py:SdoServer:on_request() Modifies lots of variables
I haven't investigated how many of these have an implicit safe design. This issue is mostly for information, but in general race conditions due to missing synchronization protection is sporadic and hard to debug.
In my work of porting canopen to asyncio, I stubled across that canopen contains a lot of unprotected thread crossings. By and large all callbacks coming from can through
Network.notify()run in another thread. This means that all subscribed callbacks must protect any class members access, otherwise interesting results may arise. Many callback handlers have synchronization mechanisms, but there a still quite a few that does not.I haven't investigated how many of these have an implicit safe design. This issue is mostly for information, but in general race conditions due to missing synchronization protection is sporadic and hard to debug.