Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2008-09

Strings and Multithreading (case)

3 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Nihilist

I thought about usings Objects in Multithreaded objects and had a to get some inspiration.

I had this problem:

one global string
two threads

lets say, both threads set the string to nil. I belive there is such a case:

Thread 1 checks for S=Nil an fpc_ansistr_decr_ref (svn version, 15.9.) Threadswitch to Thread 2
Thread 2 checks runs the whole procedure, decrements reference count to zero (only one reference (global)) and calls DisposeAnsiString
* Evil case * Memory is reallocated by someone else in Thread2 and filled with some nonsense Threadswitch to Thread 1
Thread 1 runs the rest of fpc_ansistr_decr_ref, assume integer at S-Firstoff is >0 we will suddenly decrement an integer inside a foreign memory block
* Very evil case* Integer was =1, we even free the memory again. (with many following problems and exceptions)

I really hope i am wrong. If i am not, my current solution is to put a mutex around fpc_ansistr_decr_ref, but i know that this solution is slow.

I am trying to find a better solution.

Reply by email

Jonas Maebe
to Nihilist
Nihilist wrote 16 lines
Thread 1 checks for S=Nil an fpc_ansistr_decr_ref (svn version, 15.9.) Threadswitch to Thread 2 Thread 2 checks runs the whole procedure, decrements reference count to zero (only one reference (global)) and calls DisposeAnsiString * Evil case * Memory is reallocated by someone else in Thread2 and filled with some nonsense Threadswitch to Thread 1 Thread 1 runs the rest of fpc_ansistr_decr_ref, assume integer at S- Firstoff is >0 we will suddenly decrement an integer inside a foreign memory block * Very evil case* Integer was =1, we even free the memory again. (with many following problems and exceptions) I really hope i am wrong. If i am not, my current solution is to put a mutex around fpc_ansistr_decr_ref, but i know that this solution is slow.

You have a race condition in your program anyway. Even if the incref/ decref stuff was completely atomic, depending on the scheduling order the final result would either be an empty string or the original string. It's debatable whether it's better for data races to cause crashes or not, since they can be extremely difficult to debug if they don't (not that it's easy if they do, but at least it's more apparent where there may be a problem).

I think it only makes sense to guarantee thread safety of ref-counted objects to the extent that you do not have any race conditions in your program (at the semantic level, i.e., which outcome a particular operation will have depending on the scheduling order even if all operations are atomic). Otherwise the results will be unpredictable anyway.

There are several more problems besides fpc_AnsiStr_Assign() if you have such race conditions (e.g. in one thread passing the global string by value, so fpc_ansistr_incr_ref gets() called, while calling finalize() on the string in another thread (so fpc_ansistr_decr_ref() gets called).

Jonas

Reply by email

Florian Klaempfl
to Nihilist: I thought about usings Objects in Multithreaded objects and had a to get some…
Show quoted text 14 lines
I thought about usings Objects in Multithreaded objects and had a look at astrings.inc to get some inspiration. I had this problem: one global string two threads lets say, both threads set the string to nil. I belive there is such a case: Thread 1 checks for S=Nil an fpc_ansistr_decr_ref (svn version, 15.9.) Threadswitch to Thread 2 Thread 2 checks runs the whole procedure, decrements reference count to zero (only one reference (global)) and calls DisposeAnsiString

This is the fault: you are accessing one data location without any syncronization

<ansistring>:=nil;

cannot be consider being an atomic operation. Even for ordinals this might be not valid:

<longint>:=0;

might not be atomic on an smp if <longint> is not aligned (on x86).

Reply by email