github.com/haraldrudell/parl@v0.4.176/g0/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  	"strings"
    10  
    11  	"github.com/haraldrudell/parl"
    12  	"github.com/haraldrudell/parl/pruntime"
    13  )
    14  
    15  const (
    16  	ThreadDataEmpty = "[empty]"
    17  	ThreadDataNil   = "threadData:nil"
    18  )
    19  
    20  // ThreadData contains identifiable information about a running thread.
    21  //   - ThreadData does not have initialization
    22  type ThreadData struct {
    23  	// threadID is the ID of the running thread
    24  	//	- a small integer with 1 for main thread, displayed by debug.Stack
    25  	threadID parl.ThreadID
    26  	// createLocation is the code line of the go-statement function-call
    27  	// invocation launching the thread
    28  	createLocation pruntime.CodeLocation
    29  	// funcLocation is the code line of the function of the running thread.
    30  	funcLocation pruntime.CodeLocation
    31  	// optional thread-name assigned by consumer
    32  	label string
    33  }
    34  
    35  var _ parl.ThreadData = &ThreadData{}
    36  
    37  // Update populates this object from a stack trace.
    38  func (t *ThreadData) Update(
    39  	threadID parl.ThreadID,
    40  	createInvocation, goFunction *pruntime.CodeLocation,
    41  	label string) {
    42  	if !t.threadID.IsValid() && threadID.IsValid() {
    43  		t.threadID = threadID
    44  	}
    45  	if createInvocation != nil && !t.createLocation.IsSet() && createInvocation.IsSet() {
    46  		t.createLocation = *createInvocation
    47  	}
    48  	if goFunction != nil && !t.funcLocation.IsSet() && goFunction.IsSet() {
    49  		t.funcLocation = *goFunction
    50  	}
    51  	if t.label == "" && label != "" {
    52  		t.label = label
    53  	}
    54  }
    55  
    56  // SetCreator gets preliminary Go identifier: the line invoking Go()
    57  func (t *ThreadData) SetCreator(cl *pruntime.CodeLocation) {
    58  	t.createLocation = *cl
    59  }
    60  
    61  // threadID is the ID of the running thread
    62  func (t *ThreadData) ThreadID() (threadID parl.ThreadID) {
    63  	return t.threadID
    64  }
    65  
    66  func (t *ThreadData) Create() (createLocation *pruntime.CodeLocation) {
    67  	return &t.createLocation
    68  }
    69  
    70  func (t *ThreadData) Func() (funcLocation *pruntime.CodeLocation) {
    71  	return &t.funcLocation
    72  }
    73  
    74  func (t *ThreadData) Name() (label string) {
    75  	return t.label
    76  }
    77  
    78  func (t *ThreadData) Get() (threadID parl.ThreadID, createLocation pruntime.CodeLocation,
    79  	funcLocation pruntime.CodeLocation, label string) {
    80  	threadID = t.threadID
    81  	createLocation = t.createLocation
    82  	funcLocation = t.funcLocation
    83  	label = t.label
    84  	return
    85  }
    86  
    87  // "myThreadName:4"
    88  func (t *ThreadData) Short() (s string) {
    89  
    90  	// handle nil case
    91  	if t == nil {
    92  		return ThreadDataNil // "threadData:nil"
    93  	}
    94  
    95  	// "[label]:[threadID]"
    96  	if t.label != "" {
    97  		s = t.label
    98  	}
    99  	if t.threadID.IsValid() {
   100  		if s != "" {
   101  			s += ":" + t.threadID.String()
   102  		} else {
   103  			s = t.threadID.String()
   104  		}
   105  	}
   106  	if s != "" {
   107  		return
   108  	}
   109  
   110  	// zero-value case
   111  	return t.String()
   112  }
   113  
   114  func (t *ThreadData) LabeledString() (s string) {
   115  	var sL []string
   116  	if t.label != "" {
   117  		sL = append(sL, "label: "+t.label)
   118  	}
   119  	if t.threadID.IsValid() {
   120  		sL = append(sL, "threadID: "+t.threadID.String())
   121  	}
   122  	if t.funcLocation.IsSet() {
   123  		sL = append(sL, "go-function: "+t.funcLocation.Short())
   124  	}
   125  	if t.createLocation.IsSet() {
   126  		sL = append(sL, "go-statement: "+t.createLocation.Short())
   127  	}
   128  	if len(sL) > 0 {
   129  		s = strings.Join(sL, "\x20")
   130  	} else {
   131  		s = "[no data]"
   132  	}
   133  	return
   134  }
   135  
   136  // "myThreadName:4_func:testing.tRunner()-testing.go:1446_cre:testing.(*T).Run()-testing.go:1493"
   137  func (t *ThreadData) String() (s string) {
   138  	var sList []string
   139  	var s1 string
   140  	if t.label != "" {
   141  		s1 = t.label
   142  	}
   143  	if t.threadID.IsValid() {
   144  		if s1 != "" {
   145  			s1 += ":" + t.threadID.String()
   146  		} else {
   147  			s1 = t.threadID.String()
   148  		}
   149  	}
   150  	if s1 != "" {
   151  		sList = append(sList, s1)
   152  	}
   153  	if t.funcLocation.IsSet() {
   154  		sList = append(sList, "func:"+t.funcLocation.Short())
   155  	}
   156  	if t.createLocation.IsSet() {
   157  		sList = append(sList, "cre:"+t.createLocation.Short())
   158  	}
   159  	if s = strings.Join(sList, "_"); s == "" {
   160  		s = ThreadDataEmpty
   161  	}
   162  	return
   163  }