== Quote from Steven Schveighoffer ([email protected])'s article > On Mon, 29 Nov 2010 10:58:05 -0500, dsimcha <[email protected]> wrote: > > == Quote from Steven Schveighoffer ([email protected])'s article > >> On Wed, 17 Nov 2010 12:09:11 -0500, dsimcha <[email protected]> wrote: > >> > == Quote from Steven Schveighoffer ([email protected])'s article > >> >> The issue is that if you append to such an array and it adds more > >> pages > >> >> in > >> >> place, the block length location will move. Since each thread caches > >> >> its > >> >> own copy of the block info, one will be wrong and look at array data > >> >> thinking it's a length field. > >> >> Even if you surround the appends with a lock, it will still cause > >> >> problems > >> >> because of the cache. I'm not sure there's any way to reliably > >> append > >> >> to > >> >> such data from multiple threads. > >> >> -Steve > >> > > >> > Would assumeSafeAppend() do the trick? > >> > > >> No, that does not affect your cache. I probably should add a function > >> to > >> append without using the cache. > >> -Steve > > > > How about using std.array.Appender? This looks safe as far as I can > > tell, but I > > want to make sure there aren't any obscure implementation details that > > would > > prevent this from working, too. > That should be fine, std.array.Appender does not affect the LRU cache. In > fact, if you try to do normal appending to an array built with Appender, > it will automatically reallocate because the memory does not have the > APPENDABLE bit set (new GC bit I added to avoid misinterpretations). > This is a good solution. > -Steve
Sounds like a good solution to me, too. As long as this situation is unlikely to change in the future, I think we should scrap the idea of making appending to __gshared using ~= safe with manual synchronization, BUT the following needs to be documented: 1. Due to obscure implementation details, it is **not** safe to append to a non-shared array even if you synchronize manually. 2. If you're doing low-level shared-memory cowboy multithreading, Appender is the correct solution. 3. In general, any data structure, etc. in Phobos/druntime that can't be made thread-safe by using a synchronized/shared wrapper or manual synchronization due to obscure implementation details (especially if this would be safe with a textbook implementation) should come with an **bold** or ALL CAPS explicit warning against doing such things.
