Working towards using poll() on unix like systems.
A number of small changes designed to separate the actual socket handling from the rest of the logic in ThreadSocketHandler.
Working towards using poll() on unix like systems.
A number of small changes designed to separate the actual socket handling from the rest of the logic in ThreadSocketHandler.
utACK. Aside, this was much more easily reviewed with ?w=1
Tagged with "Refactor", as this is supposed to not change behavior?
@MarcoFalke The only change to the logic is grouping the InactivityChecks in a single function outside of the reference counting guards, that logic sets fDisconnect flags, which wont do anything until the next loop in the thread anyways.
1274 | - nPrevNodeCount = vNodesSize; 1275 | - if(clientInterface) 1276 | - clientInterface->NotifyNumConnectionsChanged(vNodesSize); 1277 | + } 1278 | + if(vNodesSize != nPrevNodeCount) { 1279 | + nPrevNodeCount = vNodesSize;
This assignment is redundant, right? :-)
It is indeed.
re-utACK
1224 | - if(vNodesSize != nPrevNodeCount) { 1225 | - nPrevNodeCount = vNodesSize; 1226 | - if(clientInterface) 1227 | - clientInterface->NotifyNumConnectionsChanged(vNodesSize); 1228 | + if(clientInterface && vNodesSize != nPrevNodeCount) { 1229 | + clientInterface->NotifyNumConnectionsChanged(vNodesSize);
Commit "Improve lock handling in DisconnectNodes."
Is it worth preventing notifying the same connection count?
Yes, it triggers a notification that updates the GUI and would happen every 50ms.
1223 | - } 1224 | - if(vNodesSize != nPrevNodeCount) { 1225 | - nPrevNodeCount = vNodesSize; 1226 | - if(clientInterface) 1227 | - clientInterface->NotifyNumConnectionsChanged(vNodesSize); 1228 | + if(clientInterface && vNodesSize != nPrevNodeCount) {
Commit "Improve lock handling in DisconnectNodes."
nit, space after if.
fixed
1221 | @@ -1222,6 +1222,13 @@ void CConnman::DisconnectNodes() { 1222 | } 1223 | } 1224 | 1225 | +void CConnman::InactivityChecks() { 1226 | + LOCK(cs_vNodes); 1227 | + for (CNode* pnode : vNodes) { 1228 | + InactivityCheck(pnode);
Commit "Move InactivityChecks logic to private method."
Just noting that with this change InactivityCheck is now called with cs_vNodes locked.
The reasoning here is that the contents of InactivityCheck are virtually instant.
If this causes any issues in the future it can be trivially switched back to using reference counting.
1232 | -void CConnman::InactivityCheck(CNode *pnode) { 1233 | int64_t nMicroTime = GetTimeMicros(); 1234 | int64_t nTime = nMicroTime / 1000000; 1235 | - if (nTime - pnode->nTimeConnected > 60) 1236 | + 1237 | {
Commit "Merge InactivityCheck into InactivityChecks."
Could remove this block?
Not sure what you mean here
I mean like this:
void CConnman::InactivityChecks() {
LOCK(cs_vNodes);
int64_t nMicroTime = GetTimeMicros();
int64_t nTime = nMicroTime / 1000000;
for (CNode* pnode : vNodes) {
if (nTime - pnode->nTimeConnected > 60)
...
yeah good point, the lock could take a while
1228 | - InactivityCheck(pnode); 1229 | - } 1230 | -} 1231 | - 1232 | -void CConnman::InactivityCheck(CNode *pnode) { 1233 | int64_t nMicroTime = GetTimeMicros();
Commit "Merge InactivityCheck into InactivityChecks."
Should be after LOCK(cs_vNodes)?
Not sure what you mean here
Move the call GetTimeMicros after the lock?
Ah I see
Concept ACK.
I don't believe this is correct. NotifyNumConnectionsChanged will now only be called when nodes are disconnected, and no longer when nodes are connected. Also moving the notify into the DisconnectNodes member function is confusing. I'd prefer to move it into a static void NotifyNodeCount(CConman* cm, unsigned& prev_node_count) {...}. Note the static, to prevent having it to put into the header file and bloat it unnecessarily. (Imo you could do this as well for the other functions)
Let me know if I am mistaken in some way.
Also, it would help to see the code that builds on top of this refactor. This way it is easier to see why the refactor is required and why it was done in exactly this way.
1283 | +void CConnman::InactivityChecks() { 1284 | + int64_t nMicroTime, nTime; 1285 | + 1286 | + { 1287 | + LOCK(cs_vNodes); 1288 | + nMicroTime = GetTimeMicros();
in commit e92a917117 Reduce calls to GetMicroTime in InactivityCheck.
newly introduced variables should always be snake_case, e.g. time_micro = ... .
1287 | +{ 1288 | + unsigned int nPrevNodeCount = 0; 1289 | + while (!interruptNet) 1290 | + { 1291 | + // 1292 | + // Disconnect nodes
In commit "Move DisconnectNodes logic to private method." (7c203fb5ab2558cd6e306d85a62c8bbe159a7c02)
Should delete this comment I think. It just takes up space and conveys no information.
1152 | @@ -1153,82 +1153,86 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) { 1153 | } 1154 | } 1155 | 1156 | -void CConnman::ThreadSocketHandler() 1157 | -{ 1158 | - unsigned int nPrevNodeCount = 0; 1159 | - while (!interruptNet) 1160 | +void CConnman::DisconnectNodes(unsigned int &nPrevNodeCount) {
In commit "Move DisconnectNodes logic to private method." (7c203fb5ab2558cd6e306d85a62c8bbe159a7c02)
Opening brace should go on next line.
1189 | @@ -1190,6 +1190,8 @@ void CConnman::DisconnectNodes() { 1190 | vNodesDisconnected.push_back(pnode); 1191 | } 1192 | } 1193 | + 1194 | + vNodesSize = vNodes.size();
In commit "Improve lock handling in DisconnectNodes." (57bd308a09556960e8fab1cd44f61ef519058a59)
I would combine this commit with the previous commit "Remove nPrevNodeCount parameter" because changes in that commit like moving the vNodesSize declaration further away from its assignment, and updating the nPrevNodeCount value before throwing it away really don't make sense standalone.
Reviewed this, but the bug in commit "Remove nPrevNodeCount parameter from DisconnectNodes." (5878abfdd3fb2ff7bb6d20f16ec16b70e27ead92) which Marco pointed out needs to be fixed, and will change this PR quite a bit. Otherwise, though, the refactorings are nice.
Also, it would help to see the code that builds on top of this refactor. This way it is easier to see why the refactor is required and why it was done in exactly this way.
Doesn't use this refactor, but https://github.com/TheBlueMatt/bitcoin/commit/10b8cafcf500459c37cd228fd82220623ca17f81 from Matt shows generally what is involved in switching from select() to poll(). The changes in this PR probably just help by breaking up the large ThreadSocketHandler function more.
@MarcoFalke you're definitely right, that is a bug
i'm not so sure about making these static functions though, they extensively use CConnman variables and are only called by CConnman methods
Yeah, feel free to ignore my comment about the static vs private
@MarcoFalke ok fixed that issue and the variable naming
utACK 8491dfbadceb8052f852ebf0020a622194db525f
<!--e57a25ab6845829454e8d69fc972939a-->Note to reviewers: This pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
1266 | - vNodesSize = vNodes.size(); 1267 | - } 1268 | - if(vNodesSize != nPrevNodeCount) { 1269 | - nPrevNodeCount = vNodesSize; 1270 | - if(clientInterface) 1271 | - clientInterface->NotifyNumConnectionsChanged(vNodesSize);
In commit "Move DisconnectNodes logic to private method." (2d5c345507208d215c0621180305a9f1d363012a)
It seems like moving NotifyNumConnectionsChanged call from right after the disconnect to later in the loop below after the select call changes behavior. So instead of ui being updated immediately after a disconnection, it will only be updated after a disconnect followed by a receive on another socket? Is this correct / intentional / good?
Select timeout is 50ms, doesn't seem to particularly matter.
Can certainly change it back though, it really shouldn't matter.
1254 | @@ -1255,9 +1255,22 @@ void CConnman::InactivityChecks() 1255 | } 1256 | } 1257 | 1258 | +void CConnman::NotifyNumConnectionsChanged()
In commit "Move NotifyNumConnectionsChanged logic to private method." (e817ce3090fa71c61170216090685ee142d0f1d5)
It would be nice if you combined this commit with commit "Move DisconnectNodes logic to private method" (2d5c345507208d215c0621180305a9f1d363012a), or moved this commit before it, so this block of code only moves once instead of twice inside the same PR.
I've restructured the first commit so that the logic isn't moved the first time.
1259 | @@ -1260,6 +1260,7 @@ void CConnman::ThreadSocketHandler() 1260 | unsigned int nPrevNodeCount = 0; 1261 | while (!interruptNet) 1262 | { 1263 | + InactivityChecks();
In commit "Run InactivityChecks before other socket handling logic." (8491dfbadceb8052f852ebf0020a622194db525f)
It seems like this commit should have no effect, but if it has no effect, then it's not clear why it would be desirable? I think it would be helpful if the commit messages in this PR said explicitly whether the commit is or isn't intending to change behavior.
It doesn't really matter, but running it earlier might allow for marking nodes disconnected before the socket handling logic runs.
utACK 672543085ac4973f034ad30f897230581a2af8d2. Only changes since last review are dropping the "Run InactivityChecks before other socket handling logic" commit and tweaking order of changes to avoid moving the same code twice.