gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

watch.go (5557B)


      1 // Copyright 2021 The Libc Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package libc // import "modernc.org/libc"
      6 
      7 import (
      8 	"fmt"
      9 	"math"
     10 	"os"
     11 	"sync"
     12 	"unsafe"
     13 )
     14 
     15 var (
     16 	watches   = map[uintptr]watch{}
     17 	watchesMu sync.Mutex
     18 )
     19 
     20 type watch interface {
     21 	msg() string
     22 }
     23 
     24 type watcher string
     25 
     26 func (w watcher) msg() string {
     27 	if w == "" {
     28 		return ""
     29 	}
     30 
     31 	return fmt.Sprintf(": %s", w)
     32 }
     33 
     34 type watchInt8 struct {
     35 	val int8
     36 	watcher
     37 }
     38 
     39 func WatchInt8(p uintptr, msg string) {
     40 	watchesMu.Lock()
     41 	watches[p] = &watchInt8{*(*int8)(unsafe.Pointer(p)), watcher(msg)}
     42 	watchesMu.Unlock()
     43 }
     44 
     45 type watchUint8 struct {
     46 	val uint8
     47 	watcher
     48 }
     49 
     50 func WatchUint8(p uintptr, msg string) {
     51 	watchesMu.Lock()
     52 	watches[p] = &watchUint8{*(*uint8)(unsafe.Pointer(p)), watcher(msg)}
     53 	watchesMu.Unlock()
     54 }
     55 
     56 type watchInt16 struct {
     57 	val int16
     58 	watcher
     59 }
     60 
     61 func WatchInt16(p uintptr, msg string) {
     62 	watchesMu.Lock()
     63 	watches[p] = &watchInt16{*(*int16)(unsafe.Pointer(p)), watcher(msg)}
     64 	watchesMu.Unlock()
     65 }
     66 
     67 type watchUint16 struct {
     68 	val uint16
     69 	watcher
     70 }
     71 
     72 func WatchUint16(p uintptr, msg string) {
     73 	watchesMu.Lock()
     74 	watches[p] = &watchUint16{*(*uint16)(unsafe.Pointer(p)), watcher(msg)}
     75 	watchesMu.Unlock()
     76 }
     77 
     78 type watchInt32 struct {
     79 	val int32
     80 	watcher
     81 }
     82 
     83 func WatchInt32(p uintptr, msg string) {
     84 	watchesMu.Lock()
     85 	watches[p] = &watchInt32{*(*int32)(unsafe.Pointer(p)), watcher(msg)}
     86 	watchesMu.Unlock()
     87 }
     88 
     89 type watchUint32 struct {
     90 	val uint32
     91 	watcher
     92 }
     93 
     94 func WatchUint32(p uintptr, msg string) {
     95 	watchesMu.Lock()
     96 	watches[p] = &watchUint32{*(*uint32)(unsafe.Pointer(p)), watcher(msg)}
     97 	watchesMu.Unlock()
     98 }
     99 
    100 type watchInt64 struct {
    101 	val int64
    102 	watcher
    103 }
    104 
    105 func WatchInt64(p uintptr, msg string) {
    106 	watchesMu.Lock()
    107 	watches[p] = &watchInt64{*(*int64)(unsafe.Pointer(p)), watcher(msg)}
    108 	watchesMu.Unlock()
    109 }
    110 
    111 type watchUint64 struct {
    112 	val uint64
    113 	watcher
    114 }
    115 
    116 func WatchUint64(p uintptr, msg string) {
    117 	watchesMu.Lock()
    118 	watches[p] = &watchUint64{*(*uint64)(unsafe.Pointer(p)), watcher(msg)}
    119 	watchesMu.Unlock()
    120 }
    121 
    122 type watchFloat32 struct {
    123 	val float32
    124 	watcher
    125 }
    126 
    127 func WatchFloat32(p uintptr, msg string) {
    128 	watchesMu.Lock()
    129 	watches[p] = &watchFloat32{*(*float32)(unsafe.Pointer(p)), watcher(msg)}
    130 	watchesMu.Unlock()
    131 }
    132 
    133 type watchFloat64 struct {
    134 	val float64
    135 	watcher
    136 }
    137 
    138 func WatchFloat64(p uintptr, msg string) {
    139 	watchesMu.Lock()
    140 	watches[p] = &watchFloat64{*(*float64)(unsafe.Pointer(p)), watcher(msg)}
    141 	watchesMu.Unlock()
    142 }
    143 
    144 type watchPtr struct {
    145 	val uintptr
    146 	watcher
    147 }
    148 
    149 func WatchPtr(p uintptr, msg string) {
    150 	watchesMu.Lock()
    151 	watches[p] = &watchPtr{*(*uintptr)(unsafe.Pointer(p)), watcher(msg)}
    152 	watchesMu.Unlock()
    153 }
    154 
    155 func Watch() {
    156 	watchesMu.Lock()
    157 	flush := false
    158 	for p, v := range watches {
    159 		switch x := v.(type) {
    160 		case *watchInt8:
    161 			if val := *(*int8)(unsafe.Pointer(p)); val != x.val {
    162 				flush = true
    163 				fmt.Fprintf(os.Stderr, "%v: int8@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
    164 				x.val = val
    165 			}
    166 		case *watchUint8:
    167 			if val := *(*uint8)(unsafe.Pointer(p)); val != x.val {
    168 				flush = true
    169 				fmt.Fprintf(os.Stderr, "%v: uint8@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
    170 				x.val = val
    171 			}
    172 		case *watchInt16:
    173 			if val := *(*int16)(unsafe.Pointer(p)); val != x.val {
    174 				flush = true
    175 				fmt.Fprintf(os.Stderr, "%v: int16@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
    176 				x.val = val
    177 			}
    178 		case *watchUint16:
    179 			if val := *(*uint16)(unsafe.Pointer(p)); val != x.val {
    180 				flush = true
    181 				fmt.Fprintf(os.Stderr, "%v: uint16@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
    182 				x.val = val
    183 			}
    184 		case *watchInt32:
    185 			if val := *(*int32)(unsafe.Pointer(p)); val != x.val {
    186 				flush = true
    187 				fmt.Fprintf(os.Stderr, "%v: int32@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
    188 				x.val = val
    189 			}
    190 		case *watchUint32:
    191 			if val := *(*uint32)(unsafe.Pointer(p)); val != x.val {
    192 				flush = true
    193 				fmt.Fprintf(os.Stderr, "%v: uint32@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
    194 				x.val = val
    195 			}
    196 		case *watchInt64:
    197 			if val := *(*int64)(unsafe.Pointer(p)); val != x.val {
    198 				flush = true
    199 				fmt.Fprintf(os.Stderr, "%v: int64@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
    200 				x.val = val
    201 			}
    202 		case *watchUint64:
    203 			if val := *(*uint64)(unsafe.Pointer(p)); val != x.val {
    204 				flush = true
    205 				fmt.Fprintf(os.Stderr, "%v: uint64@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
    206 				x.val = val
    207 			}
    208 		case *watchFloat32:
    209 			if val := *(*float32)(unsafe.Pointer(p)); math.Float32bits(val) != math.Float32bits(x.val) {
    210 				flush = true
    211 				fmt.Fprintf(os.Stderr, "%v: float32@%#x was %v(%#x), new %v(%#x)%s\n", origin(2), p, x.val, math.Float32bits(x.val), val, math.Float32bits(val), x.msg())
    212 				x.val = val
    213 			}
    214 		case *watchFloat64:
    215 			if val := *(*float64)(unsafe.Pointer(p)); math.Float64bits(val) != math.Float64bits(x.val) {
    216 				flush = true
    217 				fmt.Fprintf(os.Stderr, "%v: float64@%#x was %v(%#x), new %v(%#x)%s\n", origin(2), p, x.val, math.Float64bits(x.val), val, math.Float64bits(val), x.msg())
    218 				x.val = val
    219 			}
    220 		case *watchPtr:
    221 			if val := *(*uintptr)(unsafe.Pointer(p)); val != x.val {
    222 				flush = true
    223 				fmt.Fprintf(os.Stderr, "%v: ptr@%#x was %#x, new %#x%s\n", origin(2), p, x.val, val, x.msg())
    224 				x.val = val
    225 			}
    226 		default:
    227 			panic(todo("%T", x))
    228 		}
    229 	}
    230 	if flush {
    231 		os.Stderr.Sync()
    232 	}
    233 	watchesMu.Unlock()
    234 }
    235 
    236 func WatchDelete(p uintptr) {
    237 	watchesMu.Lock()
    238 	delete(watches, p)
    239 	watchesMu.Unlock()
    240 }