It is sometimes useful for a thread to distinguish itself from any other created threads in an application. For example, if two threads in a four thread application establish a producer-consumer relationship, it can be useful for the two cooperating threads to find out what each other's thread handles are. Once these handles are obtained, all synchronization can be done using only the CBL_THREAD_SUSPEND and CBL_THREAD_RESUME calls. If each thread in the application creates a name for itself (and the name relates to its functionality) and associates the name with its thread handle, then the cooperating threads can scan the thread name list and find each other's handle.
Another possible use for associating globally accessible data to each thread and its handle is to hold a termination flag, obviating the possible need to use CBL_THREAD_KILL. Each thread in the application can poll its termination flag to check for a termination request. The terminating thread can then make sure no locks are held and no synchronization actions are required before terminating normally.
Globally accessible data for a thread is associated with the thread handle by the CBL_THREAD_IDDATA_ALLOC routine executed within the thread. This data is retrieved by the CBL_THREAD_IDDATA_GET routine, if the thread handle is already known, or by the CBL_THREAD_LIST_n routines if the thread handle is not yet known.
Example - Associating Globally Accessible Data With a Thread Handle
The following example shows how to associate globally accessible data with the thread handle by using the CBL_THREAD_IDDATA_ALLOC call executed within the thread. The data is retrieved by the CBL_THREAD_IDDATA_GET call, if the thread handle is already known, or by the CBL_THREAD_LIST_n routines if the thread handle is not yet known.
      *************** MAINPROG.CBL ************************
       identification division.
       program-id. mainprog.
      
       Data Division.
       Local-Storage Section.
       01 ret-wait         usage pointer.
       01 iddata-ptr       usage pointer.
       01 sub-iddata-ptr   usage pointer.
       01 sub-handle       usage thread-pointer.
       Linkage Section.
        01 iddata-record.
           05 iddata-name  pic x(20).
         05 iddata-term    pic x comp-x value 0.
      
       Procedure Division.
      
      * Establish identification data - don't provide 
      * initialization data when it is allocated, instead
      * initialize it after the pointer is retrieved.
      
           call 'CBL_THREAD_IDDATA_ALLOC' using 
                                          by value zero
                                          length of iddata-record
           call 'CBL_THREAD_IDDATA_GET'   using iddata-ptr
                                                omitted
           set address of iddata-record to iddata-ptr
           move 'main' to iddata-name
      
      * Create sub-thread
      
           start 'SUBPROG '  identified by sub-handle
      
      * Wait until child creates its iddata and then flag 
      * termination
      
           set sub-iddata-ptr to NULL
           perform until 1 = 0
               call 'CBL_THREAD_IDDATA_GET' using sub-iddata-ptr
                                            by value sub-handle
               if sub-iddata-ptr not = null
                   exit perform
               end-if
               call 'CBL_THREAD_YIELD'
           end-perform
           set address of iddata-record to sub-iddata-ptr
           move 1 to iddata-term
      
      * Wait until the child ends
           wait for sub-handle   *> clear up thread's resources
           display 'All synchronization is complete on ' &
                   'RTS termination'
           stop run.
       end program mainprog.
      *************** SUBPROG.CBL ************************
       identification division.
       program-id. subprog.
      
       Data Division.
       Working-Storage Section.
       01 sub-iddata.
          05 sub-name	          pic x(20) value 'sub'.
          05 sub-term	          pic x comp-x value 0.
       Local-Storage Section.
       01 iddata-ptr            usage pointer.
       01 thread-handle         usage pointer.
       01 thread-state          pic x(4) comp-x.
       01 parent-handle         usage pointer.
       Linkage Section.
       01 iddata-record.
          05 iddata-name        pic x(20).
          05 iddata-term        pic x comp-x value 0.
       Procedure Division.
      
      * Establish identification data - provide 
      * initialization data
           call 'CBL_THREAD_IDDATA_ALLOC'
                                using sub-iddata
                                by value length of sub-iddata
      
      * Find our parent thread and resume him
      
           call 'CBL_THREAD_LIST_START'		
                             using thread-handle
                                   thread-state
                                   iddata-ptr
           set parent-handle to NULL
           perform until thread-handle = null 
                      or return-code not = 0
               if iddata-ptr not = null
                   set address of iddata-record  to iddata-ptr
                   if iddata-name = 'main'
                       set parent-handle to thread-handle
                       exit perform
                  end-if
               end-if
               call 'CBL_THREAD_LIST_NEXT' using thread-handle
                                                 thread-state
                                                 iddata-ptr
           end-perform
           call 'CBL_THREAD_LIST_END'
           if parent-handle = NULL
               display 'synchronization error'
               stop run
           end-if
           call 'CBL_THREAD_IDDATA_GET' using iddata-ptr
                                              omitted
           set address of iddata-record to iddata-ptr
           perform until iddata-term = 1
               call 'CBL_THREAD_YIELD'
           end-perform
           exit program.
       end program subprog.    
 
               		This example establishes handshaking for thread and application termination. Note that this kind of handshaking could have been accomplished more easily by passing the handle of the main thread into the child as a parameter. This would have avoided the need to rely on identification data or to step through the thread list.
Consider the following points about this example:
The method you use in your application depends on what level of contention you expect on identification data.
If a thread uses the CBL_THREAD_LIST_n routines:
For this reason you should:
These restrictions are removed only after list stepping is terminated by a call to CBL_THREAD_LIST_END.