mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-03 18:22:25 -06:00 
			
		
		
		
	
		
			
	
	
		
			241 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			241 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								// Copyright 2021 The Libc Authors. All rights reserved.
							 | 
						||
| 
								 | 
							
								// Use of this source code is governed by a BSD-style
							 | 
						||
| 
								 | 
							
								// license that can be found in the LICENSE file.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								package libc // import "modernc.org/libc"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"fmt"
							 | 
						||
| 
								 | 
							
									"math"
							 | 
						||
| 
								 | 
							
									"os"
							 | 
						||
| 
								 | 
							
									"sync"
							 | 
						||
| 
								 | 
							
									"unsafe"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var (
							 | 
						||
| 
								 | 
							
									watches   = map[uintptr]watch{}
							 | 
						||
| 
								 | 
							
									watchesMu sync.Mutex
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type watch interface {
							 | 
						||
| 
								 | 
							
									msg() string
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type watcher string
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (w watcher) msg() string {
							 | 
						||
| 
								 | 
							
									if w == "" {
							 | 
						||
| 
								 | 
							
										return ""
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return fmt.Sprintf(": %s", w)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type watchInt8 struct {
							 | 
						||
| 
								 | 
							
									val int8
							 | 
						||
| 
								 | 
							
									watcher
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func WatchInt8(p uintptr, msg string) {
							 | 
						||
| 
								 | 
							
									watchesMu.Lock()
							 | 
						||
| 
								 | 
							
									watches[p] = &watchInt8{*(*int8)(unsafe.Pointer(p)), watcher(msg)}
							 | 
						||
| 
								 | 
							
									watchesMu.Unlock()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type watchUint8 struct {
							 | 
						||
| 
								 | 
							
									val uint8
							 | 
						||
| 
								 | 
							
									watcher
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func WatchUint8(p uintptr, msg string) {
							 | 
						||
| 
								 | 
							
									watchesMu.Lock()
							 | 
						||
| 
								 | 
							
									watches[p] = &watchUint8{*(*uint8)(unsafe.Pointer(p)), watcher(msg)}
							 | 
						||
| 
								 | 
							
									watchesMu.Unlock()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type watchInt16 struct {
							 | 
						||
| 
								 | 
							
									val int16
							 | 
						||
| 
								 | 
							
									watcher
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func WatchInt16(p uintptr, msg string) {
							 | 
						||
| 
								 | 
							
									watchesMu.Lock()
							 | 
						||
| 
								 | 
							
									watches[p] = &watchInt16{*(*int16)(unsafe.Pointer(p)), watcher(msg)}
							 | 
						||
| 
								 | 
							
									watchesMu.Unlock()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type watchUint16 struct {
							 | 
						||
| 
								 | 
							
									val uint16
							 | 
						||
| 
								 | 
							
									watcher
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func WatchUint16(p uintptr, msg string) {
							 | 
						||
| 
								 | 
							
									watchesMu.Lock()
							 | 
						||
| 
								 | 
							
									watches[p] = &watchUint16{*(*uint16)(unsafe.Pointer(p)), watcher(msg)}
							 | 
						||
| 
								 | 
							
									watchesMu.Unlock()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type watchInt32 struct {
							 | 
						||
| 
								 | 
							
									val int32
							 | 
						||
| 
								 | 
							
									watcher
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func WatchInt32(p uintptr, msg string) {
							 | 
						||
| 
								 | 
							
									watchesMu.Lock()
							 | 
						||
| 
								 | 
							
									watches[p] = &watchInt32{*(*int32)(unsafe.Pointer(p)), watcher(msg)}
							 | 
						||
| 
								 | 
							
									watchesMu.Unlock()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type watchUint32 struct {
							 | 
						||
| 
								 | 
							
									val uint32
							 | 
						||
| 
								 | 
							
									watcher
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func WatchUint32(p uintptr, msg string) {
							 | 
						||
| 
								 | 
							
									watchesMu.Lock()
							 | 
						||
| 
								 | 
							
									watches[p] = &watchUint32{*(*uint32)(unsafe.Pointer(p)), watcher(msg)}
							 | 
						||
| 
								 | 
							
									watchesMu.Unlock()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type watchInt64 struct {
							 | 
						||
| 
								 | 
							
									val int64
							 | 
						||
| 
								 | 
							
									watcher
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func WatchInt64(p uintptr, msg string) {
							 | 
						||
| 
								 | 
							
									watchesMu.Lock()
							 | 
						||
| 
								 | 
							
									watches[p] = &watchInt64{*(*int64)(unsafe.Pointer(p)), watcher(msg)}
							 | 
						||
| 
								 | 
							
									watchesMu.Unlock()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type watchUint64 struct {
							 | 
						||
| 
								 | 
							
									val uint64
							 | 
						||
| 
								 | 
							
									watcher
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func WatchUint64(p uintptr, msg string) {
							 | 
						||
| 
								 | 
							
									watchesMu.Lock()
							 | 
						||
| 
								 | 
							
									watches[p] = &watchUint64{*(*uint64)(unsafe.Pointer(p)), watcher(msg)}
							 | 
						||
| 
								 | 
							
									watchesMu.Unlock()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type watchFloat32 struct {
							 | 
						||
| 
								 | 
							
									val float32
							 | 
						||
| 
								 | 
							
									watcher
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func WatchFloat32(p uintptr, msg string) {
							 | 
						||
| 
								 | 
							
									watchesMu.Lock()
							 | 
						||
| 
								 | 
							
									watches[p] = &watchFloat32{*(*float32)(unsafe.Pointer(p)), watcher(msg)}
							 | 
						||
| 
								 | 
							
									watchesMu.Unlock()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type watchFloat64 struct {
							 | 
						||
| 
								 | 
							
									val float64
							 | 
						||
| 
								 | 
							
									watcher
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func WatchFloat64(p uintptr, msg string) {
							 | 
						||
| 
								 | 
							
									watchesMu.Lock()
							 | 
						||
| 
								 | 
							
									watches[p] = &watchFloat64{*(*float64)(unsafe.Pointer(p)), watcher(msg)}
							 | 
						||
| 
								 | 
							
									watchesMu.Unlock()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type watchPtr struct {
							 | 
						||
| 
								 | 
							
									val uintptr
							 | 
						||
| 
								 | 
							
									watcher
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func WatchPtr(p uintptr, msg string) {
							 | 
						||
| 
								 | 
							
									watchesMu.Lock()
							 | 
						||
| 
								 | 
							
									watches[p] = &watchPtr{*(*uintptr)(unsafe.Pointer(p)), watcher(msg)}
							 | 
						||
| 
								 | 
							
									watchesMu.Unlock()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func Watch() {
							 | 
						||
| 
								 | 
							
									watchesMu.Lock()
							 | 
						||
| 
								 | 
							
									flush := false
							 | 
						||
| 
								 | 
							
									for p, v := range watches {
							 | 
						||
| 
								 | 
							
										switch x := v.(type) {
							 | 
						||
| 
								 | 
							
										case *watchInt8:
							 | 
						||
| 
								 | 
							
											if val := *(*int8)(unsafe.Pointer(p)); val != x.val {
							 | 
						||
| 
								 | 
							
												flush = true
							 | 
						||
| 
								 | 
							
												fmt.Fprintf(os.Stderr, "%v: int8@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
							 | 
						||
| 
								 | 
							
												x.val = val
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case *watchUint8:
							 | 
						||
| 
								 | 
							
											if val := *(*uint8)(unsafe.Pointer(p)); val != x.val {
							 | 
						||
| 
								 | 
							
												flush = true
							 | 
						||
| 
								 | 
							
												fmt.Fprintf(os.Stderr, "%v: uint8@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
							 | 
						||
| 
								 | 
							
												x.val = val
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case *watchInt16:
							 | 
						||
| 
								 | 
							
											if val := *(*int16)(unsafe.Pointer(p)); val != x.val {
							 | 
						||
| 
								 | 
							
												flush = true
							 | 
						||
| 
								 | 
							
												fmt.Fprintf(os.Stderr, "%v: int16@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
							 | 
						||
| 
								 | 
							
												x.val = val
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case *watchUint16:
							 | 
						||
| 
								 | 
							
											if val := *(*uint16)(unsafe.Pointer(p)); val != x.val {
							 | 
						||
| 
								 | 
							
												flush = true
							 | 
						||
| 
								 | 
							
												fmt.Fprintf(os.Stderr, "%v: uint16@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
							 | 
						||
| 
								 | 
							
												x.val = val
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case *watchInt32:
							 | 
						||
| 
								 | 
							
											if val := *(*int32)(unsafe.Pointer(p)); val != x.val {
							 | 
						||
| 
								 | 
							
												flush = true
							 | 
						||
| 
								 | 
							
												fmt.Fprintf(os.Stderr, "%v: int32@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
							 | 
						||
| 
								 | 
							
												x.val = val
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case *watchUint32:
							 | 
						||
| 
								 | 
							
											if val := *(*uint32)(unsafe.Pointer(p)); val != x.val {
							 | 
						||
| 
								 | 
							
												flush = true
							 | 
						||
| 
								 | 
							
												fmt.Fprintf(os.Stderr, "%v: uint32@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
							 | 
						||
| 
								 | 
							
												x.val = val
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case *watchInt64:
							 | 
						||
| 
								 | 
							
											if val := *(*int64)(unsafe.Pointer(p)); val != x.val {
							 | 
						||
| 
								 | 
							
												flush = true
							 | 
						||
| 
								 | 
							
												fmt.Fprintf(os.Stderr, "%v: int64@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
							 | 
						||
| 
								 | 
							
												x.val = val
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case *watchUint64:
							 | 
						||
| 
								 | 
							
											if val := *(*uint64)(unsafe.Pointer(p)); val != x.val {
							 | 
						||
| 
								 | 
							
												flush = true
							 | 
						||
| 
								 | 
							
												fmt.Fprintf(os.Stderr, "%v: uint64@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
							 | 
						||
| 
								 | 
							
												x.val = val
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case *watchFloat32:
							 | 
						||
| 
								 | 
							
											if val := *(*float32)(unsafe.Pointer(p)); math.Float32bits(val) != math.Float32bits(x.val) {
							 | 
						||
| 
								 | 
							
												flush = true
							 | 
						||
| 
								 | 
							
												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())
							 | 
						||
| 
								 | 
							
												x.val = val
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case *watchFloat64:
							 | 
						||
| 
								 | 
							
											if val := *(*float64)(unsafe.Pointer(p)); math.Float64bits(val) != math.Float64bits(x.val) {
							 | 
						||
| 
								 | 
							
												flush = true
							 | 
						||
| 
								 | 
							
												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())
							 | 
						||
| 
								 | 
							
												x.val = val
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case *watchPtr:
							 | 
						||
| 
								 | 
							
											if val := *(*uintptr)(unsafe.Pointer(p)); val != x.val {
							 | 
						||
| 
								 | 
							
												flush = true
							 | 
						||
| 
								 | 
							
												fmt.Fprintf(os.Stderr, "%v: ptr@%#x was %#x, new %#x%s\n", origin(2), p, x.val, val, x.msg())
							 | 
						||
| 
								 | 
							
												x.val = val
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										default:
							 | 
						||
| 
								 | 
							
											panic(todo("%T", x))
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if flush {
							 | 
						||
| 
								 | 
							
										os.Stderr.Sync()
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									watchesMu.Unlock()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func WatchDelete(p uintptr) {
							 | 
						||
| 
								 | 
							
									watchesMu.Lock()
							 | 
						||
| 
								 | 
							
									delete(watches, p)
							 | 
						||
| 
								 | 
							
									watchesMu.Unlock()
							 | 
						||
| 
								 | 
							
								}
							 |