
Rob Leslie
writes:
Is this expected behavior? I realize performing any IO within an STM transaction is inherently unsafe, but I am a little surprised that ‘bracket’ fails here.
Is there a better way to do what I’m trying to accomplish? How can I provide a pure interface to my foreign function that will work within an STM transaction?
If your foreign function "depends on some global state in a way that compromises thread safety", I would hestitate to simply tell the FFI that it is pure. Instead, you can break up your STM transaction into two pieces: A first part that sets up the transaction and sets a guard variable so other transactions cannot proceed until the second part is completed, then perform the FFI call, then the second part of the transaction. For example: atomically $ do m <- readTVar mutex check (not m) writeTVar m True ... do whatever STM setup work is needed here ... ffiCall atomically $ do ... do whatever STM cleanup work is needed here ... writeTVar m False This way your ffiCall is conceptually within a larger transactional block. John