Menu

#770 ThreadCall does not ensure that data for passing parameter to a thread are still maintained until its launch

open
nobody
None
compiler
2015-02-16
2015-02-15
No

General problem:
- When Threadcall involves to pass parameters to the thread, there is no guarentee that the corresponding data are still maintained after the end of the Threadcall statement and this until the thread is launched.
- In particular, object copies (as strings) must not be destructed before the thread is launched (for these, the fault may be more obvious than data that still may remain in memory even released).
- That may cause bad behavior.


A faults example for several passing types:

Dim Shared As Any Ptr m
m = Mutexcreate()
Dim As Any Ptr p(19)
Dim As Integer K

Sub threadByVal (Byval I As Integer)
  Mutexlock(m)
  Print @I, Str(I)
  Mutexunlock(m)
End Sub

Sub threadByRef (Byref I As Integer)
  Mutexlock(m)
  Print @I, Str(I)
  Mutexunlock(m)
End Sub

Print "Adress", "Data value"
Print
For I As Integer = 0 To 9
  p(I) = Threadcall threadByVal(I)
Next I
For I As Integer = 0 To 9
  Threadwait(p(I))
Next I
Print

For K = 10 To 19
  p(K) = Threadcall threadByRef(K)
Next K
For I As Integer = 10 To 19
  Threadwait(p(I))
Next I

Mutexdestroy(m)
Sleep

Output:

Adress        Data value

10485420      1
11533996      3
13631148      4
15728300      7
16776876      1
18874028      1
12582572      1
14679724      2
10485420      2
17825452      2

1244800       13
1244800       18
1244800       20
1244800       20
11            Appuyez sur une touche pour continuer...

First part of example with parameter passed by value:
- The data should be correctly incremented from 0 to 9 because a copy of each iterator data is passed by value.

Second part of example with parameter passed by reference:
- The fault is not the rapid incrementation of the displayed data of the iterator because it is passed by reference (there is no temporary variables involved by ThreadCall) and each value is not frozen until the thread is launched.
- But the address of the reference should be maintained until the thread is launched, instead of, a wrong address value is passed to the thread ('11' instead of '1244800' in the above example), then the program crashes when it tries to access it.


Referring at forum, from the post:
http://www.freebasic.net/forum/viewtopic.php?p=205239#p205239

Discussion

  • fxm (freebasic.net)

    Rewording of the analysis above:

    First part of example with parameter passed by value:
    - The data should be correctly incremented from 0 to 9 equi-distributed (not necessarily in the order) between 0 and 9 because a copy of each iterator data is passed by value.

     
  • fxm (freebasic.net)

    Another malfunction with respect to the below extract of the ThreadCall documentation:

    While most subroutines are supported, the following types of subroutines may not be called:
    - Subroutines using variable arguments
    - Subroutines with unions which are passed Byval
    - Subroutines with user types containing unions, arrays, strings, or bitfields which are passed Byval


    In fact, ThreadCall also refuses the subroutines with arguments like described above:
    - unions
    - user types containing unions, arrays, strings, or bitfields
    but even if they are passed Byref !

    Type UDT
      As String s
    End Type
    
    Sub thread (Byref u As UDT)
    End Sub
    
    Dim As UDT u
    Dim As Any Ptr p = Threadcall thread(u)
    

    error 287: Unsupported function in 'Dim As Any Ptr p = Threadcall thread(u)'

    For now, a workaround is to pass pointers Byval.

     

Log in to post a comment.