github.com/haraldrudell/parl@v0.4.176/g0/thread-safe-thread-data.go (about)

     1  /*
     2  © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package g0
     7  
     8  import (
     9  	"sync"
    10  	"sync/atomic"
    11  
    12  	"github.com/haraldrudell/parl"
    13  	"github.com/haraldrudell/parl/pruntime"
    14  )
    15  
    16  // ThreadSafeThreadData controls access to a ThreadData object making it thread-safe.
    17  //   - ThreadSafeThreadData does not have initialization
    18  //   - haveThreadID indicates whether data is present
    19  type ThreadSafeThreadData struct {
    20  	haveThreadID atomic.Bool
    21  
    22  	lock sync.RWMutex
    23  	td   ThreadData
    24  }
    25  
    26  func NewThreadSafeThreadData() (t *ThreadSafeThreadData) {
    27  	return &ThreadSafeThreadData{}
    28  }
    29  
    30  // HaveThreadID indicates whether Update has been invoked on this ThreadDataWrap
    31  // object.
    32  func (tw *ThreadSafeThreadData) HaveThreadID() (haveThreadID bool) {
    33  	return tw.haveThreadID.Load()
    34  }
    35  
    36  // Update populates the wrapped ThreadData from the stack trace.
    37  func (tw *ThreadSafeThreadData) Update(
    38  	threadID parl.ThreadID,
    39  	createInvocation *pruntime.CodeLocation,
    40  	goFunction *pruntime.CodeLocation,
    41  	label string,
    42  ) {
    43  	tw.lock.Lock()
    44  	defer tw.lock.Unlock()
    45  
    46  	tw.td.Update(threadID, createInvocation, goFunction, label)
    47  	if threadID.IsValid() {
    48  		tw.haveThreadID.Store(true) // if we know have a vald ThreadID
    49  	}
    50  }
    51  
    52  // SetCreator gets preliminary Go identifier: the line invoking Go().
    53  func (tw *ThreadSafeThreadData) SetCreator(cl *pruntime.CodeLocation) {
    54  	tw.lock.Lock()
    55  	defer tw.lock.Unlock()
    56  
    57  	tw.td.SetCreator(cl)
    58  }
    59  
    60  // Get returns a clone of the wrapped ThreadData object.
    61  func (tw *ThreadSafeThreadData) Get() (thread *ThreadData) {
    62  	tw.lock.RLock()
    63  	defer tw.lock.RUnlock()
    64  
    65  	// duplicate ThreadData object
    66  	t := tw.td
    67  	thread = &t
    68  
    69  	return
    70  }
    71  
    72  // ThreadID returns the thread id of the running thread or zero if
    73  // thread ID is missing.
    74  func (tw *ThreadSafeThreadData) ThreadID() (threadID parl.ThreadID) {
    75  	tw.lock.RLock()
    76  	defer tw.lock.RUnlock()
    77  
    78  	return tw.td.ThreadID()
    79  }