Henrik Bengtsson
2016-Oct-30 18:38 UTC
[Rd] closeAllConnections() can really mess things up
This is what I get on R 3.3.1 on Linux:> con1 <- textConnection("foo1", open = "w") > print(con1)description class mode text "foo1" "textConnection" "w" "text" opened can read can write "opened" "no" "yes"> closeAllConnections() > con2 <- textConnection("foo2", open = "w")## Hmm... at this point, con1 point to con2.> print(con1)description class mode text "foo2" "textConnection" "w" "text" opened can read can write "opened" "no" "yes"> all.equal(con2, con1)[1] TRUE Hmm... that looks it could potentially mess up things badly if some code / user calls closeAllConnections(), then other connections are opened after that, and then there's code (e.g. via promises or finalizers) that tries to write to the original connections (resulting in writing to the new ones). I'm not sure how one can protect oneself against this. One approach that could lower the risk for mistakes is to record a checksum for the connection (think digest::digest(summary(con1))) when the connection is first opened and then each time one tried to read or write to the connect, one validate against this again. I can see how this could happen if each connection is referenced via an integer index internally. I discovered this in a case where the R session terminates (for unknown reasons) and then calls sys.save.image(). sys.save.image() calls closeAllConnections() and then save.image(). The latter triggered promises / delayed assignments to be resolved. Then each of those tries to access their previously assigned connections. At this point, those are now all closed, but the promises doesn't know and instead tries to read their connections. At least the first one will try to access the now only open connection, which is the one save.image() opened. In my case, they tried to read so they failed. /Henrik