diff options
| author | lukechampine <luke.champine@gmail.com> | 2016-04-04 18:26:08 -0400 |
|---|---|---|
| committer | lukechampine <luke.champine@gmail.com> | 2016-04-04 18:26:08 -0400 |
| commit | b7244297e49f3ec34b00d115582e892007b2044c (patch) | |
| tree | dd0971fb616019c090267a2f5baf2b4779d8c408 | |
| parent | add Go Report Card badge (diff) | |
| download | stm-b7244297e49f3ec34b00d115582e892007b2044c.tar.gz stm-b7244297e49f3ec34b00d115582e892007b2044c.tar.xz | |
expand Pointers section
| -rw-r--r-- | README.md | 33 |
1 files changed, 32 insertions, 1 deletions
@@ -91,7 +91,8 @@ See [example_santa_test.go](example_santa_test.go) for a more complex example. ## Pointers -Don't use stm to manage pointers! +Be very careful when managing pointers inside transactions! (This includes +slices, maps, and channels.) Here's why: ```go p := stm.NewVar([]byte{1,2,3}) @@ -119,6 +120,36 @@ stm.Atomically(func(tx *stm.Tx) { This is less efficient, but it preserves atomicity. +In the same vein, it would be a mistake to do this: + +```go +type foo struct { + i int +} +f := &foo{i: 2} +p := stm.NewVar(f) +stm.Atomically(func(tx *stm.Tx) { + f := tx.Get(p).(*foo) + f.i = 7 + tx.Set(p, f) +}) +``` + +...because setting `f.i` is a side-effect that escapes the transaction. Here, +the correct approach is to move the `Var` inside the struct: + +```go +type foo struct { + i *stm.Var +} +f := foo{i: stm.NewVar(2)} +stm.Atomically(func(tx *stm.Tx) { + i := tx.Get(f.i).(int) + i = 7 + tx.Set(f.i, i) +}) +``` + ## Benchmarks In synthetic benchmarks, STM seems to have a 1-5x performance penalty compared |
