The Crystal Programming Language Forum

Raise if containers accessed while being "changed"?

I remember hearing of a “sad story” of somebody passing a Map through a channel in golang and multiple threads started using it, it corrupted the Map itself by doing simultaneous insertions. Seg faults, etc.

I think golang added some “primitive” double checks for this kind of behavior (e.g. panic if accessed while being mutated).

https://golang.org/doc/go1.6#runtime

Would there be support for adding something similar in crystal?

While we’re at it, java does something similar, throws a “ConcurrentModificationException” if you mutate a Map or List while iterating over it (even in the same thread). Would there be support for adding something similar?

Wanting to decrease the potential of segfaults here…

Thanks for your thoughts.

Cheers!

It seems like it should either have tripwires or the structures by default be made thread safe? Somehow java avoids segfaults typically, I think this is part of how…

Somehow java avoids segfaults typically

Because Java has uniform object representation and GC aware to multithreading.

It is quite difficult to get Segmentation Fault in GC environment, since object remains live until there is no pointers to.

But it doesn’t mean “thread safety”. “Thread safety” is about correctness at whole.
For example:

the structures by default be made thread safe

No. Protecting each struct field with something like mutex is slow. Protecting struct is either slow or not possible in Crystal.

FAST / LOWLEVEL/ SAFE / HANDY - choose three, but not four.

Crystal is FAST, LOWLEVEL and HANDY language. It could NOT be completely SAFE.
You’ve heard of Rust? It is FAST, LOWLEVEL and tries to be SAFE. That is why it could NOT be HANDY.

Yep, Array/Hash could contain logic for non-deterministic race detection, like in Go or Java. They are relatively high-level construct, and they could hide some complexity behind.

But it could not be spread to any struct or class without noticable performance hit.

1 Like

Nice, yeah seems Java ArrayList just uses some non deterministic “best effort” checks for concurrent modification. I guess that’s probably enough.

Java’s HashMap is a different animal. I think I’ll just focus on the “easy” checks for Hash (parallel reads OK, anything else not OK).

There could be some more aggressive checks possible. Java disallows modification from “other threads” while iterating over a HashMap, and disallows modifying it from the current thread as well, might be too painful? I don’t understand the internals enough there anyway so won’t worry about it for now.