Each user procedure (to be executed in a thread) must be available under the following function signature:
Function userproc (Byval puserdata As Any Ptr) As String
in order to be compatible with the parameters of the 'ThreadInit' method:
Declare Sub ThreadInit (Byval pThread As Function (Byval As Any Ptr) As String, Byval p As Any Ptr = 0)
and perform the instance ('t') initialization by:
t.ThreadInit(@userproc [, puserdata])
The other methods are called on the instance ('t'):
t.ThreadStart() or t.ThreadStart(puserdata)
t.ThreadWait()
The different methods must be called respecting the order of the following sequence:
ThreadInit, [user code,] ThreadStart, [user code,] ThreadWait, [user code,] ThreadStart, [user code,] ThreadWait, [user code,] .....
After any 'ThreadStart'...'ThreadWait' sequence, a new user thread procedure can be initialized by calling the 'ThreadInit' method again on the same instance.
On the other hand, 'ThreadStart'...'ThreadWait' sequences can also be chained on different instances already initialized.
If using several instances (so several threads), the ordered sequences on each instance can be interlaced between instances because calling methods on different instances.
The overload method 'ThreadStart(Byval p As Any Ptr)' allows to start the user thread procedure by specifying a new parameter value, without having to call 'ThreadInit' first. The overload method 'ThreadStart()' starts the user thread procedure without modifying the parameter value.
The 'ThreadWait' method returns a 'As String' Type (by value), like the user thread function is declared (a string variable return allows to also pass a numeric value).
This user data return from the user function is accessed through the 'ThreadWait' return. It is always safe (because in this case, the user thread function has been always fully executed).
If the user doesn't want to use the return value of his thread function (to be used like for a subroutine):
- He ends his user thread function with Return "" for example.
- He calls 'ThreadWait' as a subroutine and not as a function (not accessing the value potentially returned by 'ThreadWait').
If the user want to use an existing thread subroutine, he can define a wrapper function (with an "any pointer" as parameter, calling the thread subroutine, and returning a string), and pass this function to 'ThreadInit'.
Warning: The information supplied to the user thread procedure via the passed pointer (by 'ThreadInit' or 'ThreadStart') should not be changed between 'ThreadStart' and 'ThreadWait' due to the time uncertainty on the real call of the user thread procedure in this interval.