Search code examples
haskellstm

Can this be done with STM?


Disclaimer: This can easily be done using an MVar () as a simple mutex. I'm just curios to see whether it can be done with STM.

I want to do the following atomically:

  • Read some variables.

  • Decide what I/O to perform, based on what I just read.

  • Perform the I/O.

  • Record the results in the variables.

For concreteness, suppose I want to keep track of how many bytes of input I've read, and pretend I've reached EOF after a certain number of bytes have been consumed. (OK, letting two threads read from the same file concurrently is probably a bogus thing to do in the first place, but go with me on this...)

Clearly this cannot be a single STM transaction; there's I/O in the middle. Clearly it would also be wrong to have it as two unconnected transactions. (Two threads could see that there's one byte of quota left, and both decide to read that byte.)

Is there a nice solution to this problem? Or is STM simply the wrong tool for this task?


Solution

  • I'd say STM can't do it, and it's on purpose. A piece of STM code can be restarted multiple times at various places if a transaction rolls back. What would happen if you run your transaction, it performs the I/O action and then rolls back when recording the results in the variables?

    For this reason STM computations must be pure, only with the addition of STM primitives such as STM mutable variables and arrays.