Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • oss/libraries/go/services/job-queues
1 result
Select Git revision
Show changes
...@@ -610,6 +610,7 @@ const ( ...@@ -610,6 +610,7 @@ const (
POLLRDNORM = 0x40 POLLRDNORM = 0x40
POLLWRBAND = 0x100 POLLWRBAND = 0x100
POLLWRNORM = 0x4 POLLWRNORM = 0x4
POLLRDHUP = 0x4000
) )
type CapRights struct { type CapRights struct {
......
...@@ -612,6 +612,7 @@ const ( ...@@ -612,6 +612,7 @@ const (
POLLRDNORM = 0x40 POLLRDNORM = 0x40
POLLWRBAND = 0x100 POLLWRBAND = 0x100
POLLWRNORM = 0x4 POLLWRNORM = 0x4
POLLRDHUP = 0x4000
) )
type CapRights struct { type CapRights struct {
......
...@@ -2486,7 +2486,7 @@ type XDPMmapOffsets struct { ...@@ -2486,7 +2486,7 @@ type XDPMmapOffsets struct {
type XDPUmemReg struct { type XDPUmemReg struct {
Addr uint64 Addr uint64
Len uint64 Len uint64
Chunk_size uint32 Size uint32
Headroom uint32 Headroom uint32
Flags uint32 Flags uint32
Tx_metadata_len uint32 Tx_metadata_len uint32
......
...@@ -727,6 +727,37 @@ const ( ...@@ -727,6 +727,37 @@ const (
RISCV_HWPROBE_EXT_ZBA = 0x8 RISCV_HWPROBE_EXT_ZBA = 0x8
RISCV_HWPROBE_EXT_ZBB = 0x10 RISCV_HWPROBE_EXT_ZBB = 0x10
RISCV_HWPROBE_EXT_ZBS = 0x20 RISCV_HWPROBE_EXT_ZBS = 0x20
RISCV_HWPROBE_EXT_ZICBOZ = 0x40
RISCV_HWPROBE_EXT_ZBC = 0x80
RISCV_HWPROBE_EXT_ZBKB = 0x100
RISCV_HWPROBE_EXT_ZBKC = 0x200
RISCV_HWPROBE_EXT_ZBKX = 0x400
RISCV_HWPROBE_EXT_ZKND = 0x800
RISCV_HWPROBE_EXT_ZKNE = 0x1000
RISCV_HWPROBE_EXT_ZKNH = 0x2000
RISCV_HWPROBE_EXT_ZKSED = 0x4000
RISCV_HWPROBE_EXT_ZKSH = 0x8000
RISCV_HWPROBE_EXT_ZKT = 0x10000
RISCV_HWPROBE_EXT_ZVBB = 0x20000
RISCV_HWPROBE_EXT_ZVBC = 0x40000
RISCV_HWPROBE_EXT_ZVKB = 0x80000
RISCV_HWPROBE_EXT_ZVKG = 0x100000
RISCV_HWPROBE_EXT_ZVKNED = 0x200000
RISCV_HWPROBE_EXT_ZVKNHA = 0x400000
RISCV_HWPROBE_EXT_ZVKNHB = 0x800000
RISCV_HWPROBE_EXT_ZVKSED = 0x1000000
RISCV_HWPROBE_EXT_ZVKSH = 0x2000000
RISCV_HWPROBE_EXT_ZVKT = 0x4000000
RISCV_HWPROBE_EXT_ZFH = 0x8000000
RISCV_HWPROBE_EXT_ZFHMIN = 0x10000000
RISCV_HWPROBE_EXT_ZIHINTNTL = 0x20000000
RISCV_HWPROBE_EXT_ZVFH = 0x40000000
RISCV_HWPROBE_EXT_ZVFHMIN = 0x80000000
RISCV_HWPROBE_EXT_ZFA = 0x100000000
RISCV_HWPROBE_EXT_ZTSO = 0x200000000
RISCV_HWPROBE_EXT_ZACAS = 0x400000000
RISCV_HWPROBE_EXT_ZICOND = 0x800000000
RISCV_HWPROBE_EXT_ZIHINTPAUSE = 0x1000000000
RISCV_HWPROBE_KEY_CPUPERF_0 = 0x5 RISCV_HWPROBE_KEY_CPUPERF_0 = 0x5
RISCV_HWPROBE_MISALIGNED_UNKNOWN = 0x0 RISCV_HWPROBE_MISALIGNED_UNKNOWN = 0x0
RISCV_HWPROBE_MISALIGNED_EMULATED = 0x1 RISCV_HWPROBE_MISALIGNED_EMULATED = 0x1
...@@ -734,4 +765,6 @@ const ( ...@@ -734,4 +765,6 @@ const (
RISCV_HWPROBE_MISALIGNED_FAST = 0x3 RISCV_HWPROBE_MISALIGNED_FAST = 0x3
RISCV_HWPROBE_MISALIGNED_UNSUPPORTED = 0x4 RISCV_HWPROBE_MISALIGNED_UNSUPPORTED = 0x4
RISCV_HWPROBE_MISALIGNED_MASK = 0x7 RISCV_HWPROBE_MISALIGNED_MASK = 0x7
RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE = 0x6
RISCV_HWPROBE_WHICH_CPUS = 0x1
) )
...@@ -313,6 +313,10 @@ func NewCallbackCDecl(fn interface{}) uintptr { ...@@ -313,6 +313,10 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode //sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode
//sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo //sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo
//sys setConsoleCursorPosition(console Handle, position uint32) (err error) = kernel32.SetConsoleCursorPosition //sys setConsoleCursorPosition(console Handle, position uint32) (err error) = kernel32.SetConsoleCursorPosition
//sys GetConsoleCP() (cp uint32, err error) = kernel32.GetConsoleCP
//sys GetConsoleOutputCP() (cp uint32, err error) = kernel32.GetConsoleOutputCP
//sys SetConsoleCP(cp uint32) (err error) = kernel32.SetConsoleCP
//sys SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP
//sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW //sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
//sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW //sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
//sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole //sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole
......
...@@ -1060,6 +1060,7 @@ const ( ...@@ -1060,6 +1060,7 @@ const (
SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6 SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6
SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4 SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4
SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12 SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12
SIO_UDP_NETRESET = IOC_IN | IOC_VENDOR | 15
// cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460 // cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460
......
...@@ -247,7 +247,9 @@ var ( ...@@ -247,7 +247,9 @@ var (
procGetCommandLineW = modkernel32.NewProc("GetCommandLineW") procGetCommandLineW = modkernel32.NewProc("GetCommandLineW")
procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW")
procGetComputerNameW = modkernel32.NewProc("GetComputerNameW") procGetComputerNameW = modkernel32.NewProc("GetComputerNameW")
procGetConsoleCP = modkernel32.NewProc("GetConsoleCP")
procGetConsoleMode = modkernel32.NewProc("GetConsoleMode") procGetConsoleMode = modkernel32.NewProc("GetConsoleMode")
procGetConsoleOutputCP = modkernel32.NewProc("GetConsoleOutputCP")
procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo") procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo")
procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW") procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW")
procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId") procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId")
...@@ -347,8 +349,10 @@ var ( ...@@ -347,8 +349,10 @@ var (
procSetCommMask = modkernel32.NewProc("SetCommMask") procSetCommMask = modkernel32.NewProc("SetCommMask")
procSetCommState = modkernel32.NewProc("SetCommState") procSetCommState = modkernel32.NewProc("SetCommState")
procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts") procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts")
procSetConsoleCP = modkernel32.NewProc("SetConsoleCP")
procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition") procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition")
procSetConsoleMode = modkernel32.NewProc("SetConsoleMode") procSetConsoleMode = modkernel32.NewProc("SetConsoleMode")
procSetConsoleOutputCP = modkernel32.NewProc("SetConsoleOutputCP")
procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW") procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW")
procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories") procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories")
procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW") procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW")
...@@ -2162,6 +2166,15 @@ func GetComputerName(buf *uint16, n *uint32) (err error) { ...@@ -2162,6 +2166,15 @@ func GetComputerName(buf *uint16, n *uint32) (err error) {
return return
} }
func GetConsoleCP() (cp uint32, err error) {
r0, _, e1 := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0)
cp = uint32(r0)
if cp == 0 {
err = errnoErr(e1)
}
return
}
func GetConsoleMode(console Handle, mode *uint32) (err error) { func GetConsoleMode(console Handle, mode *uint32) (err error) {
r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0) r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0)
if r1 == 0 { if r1 == 0 {
...@@ -2170,6 +2183,15 @@ func GetConsoleMode(console Handle, mode *uint32) (err error) { ...@@ -2170,6 +2183,15 @@ func GetConsoleMode(console Handle, mode *uint32) (err error) {
return return
} }
func GetConsoleOutputCP() (cp uint32, err error) {
r0, _, e1 := syscall.Syscall(procGetConsoleOutputCP.Addr(), 0, 0, 0, 0)
cp = uint32(r0)
if cp == 0 {
err = errnoErr(e1)
}
return
}
func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) { func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) {
r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0) r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0)
if r1 == 0 { if r1 == 0 {
...@@ -3038,6 +3060,14 @@ func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { ...@@ -3038,6 +3060,14 @@ func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) {
return return
} }
func SetConsoleCP(cp uint32) (err error) {
r1, _, e1 := syscall.Syscall(procSetConsoleCP.Addr(), 1, uintptr(cp), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func setConsoleCursorPosition(console Handle, position uint32) (err error) { func setConsoleCursorPosition(console Handle, position uint32) (err error) {
r1, _, e1 := syscall.Syscall(procSetConsoleCursorPosition.Addr(), 2, uintptr(console), uintptr(position), 0) r1, _, e1 := syscall.Syscall(procSetConsoleCursorPosition.Addr(), 2, uintptr(console), uintptr(position), 0)
if r1 == 0 { if r1 == 0 {
...@@ -3054,6 +3084,14 @@ func SetConsoleMode(console Handle, mode uint32) (err error) { ...@@ -3054,6 +3084,14 @@ func SetConsoleMode(console Handle, mode uint32) (err error) {
return return
} }
func SetConsoleOutputCP(cp uint32) (err error) {
r1, _, e1 := syscall.Syscall(procSetConsoleOutputCP.Addr(), 1, uintptr(cp), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func SetCurrentDirectory(path *uint16) (err error) { func SetCurrentDirectory(path *uint16) (err error) {
r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
if r1 == 0 { if r1 == 0 {
......
...@@ -288,7 +288,7 @@ func AfterQuery(db *gorm.DB) { ...@@ -288,7 +288,7 @@ func AfterQuery(db *gorm.DB) {
// clear the joins after query because preload need it // clear the joins after query because preload need it
if v, ok := db.Statement.Clauses["FROM"].Expression.(clause.From); ok { if v, ok := db.Statement.Clauses["FROM"].Expression.(clause.From); ok {
fromClause := db.Statement.Clauses["FROM"] fromClause := db.Statement.Clauses["FROM"]
fromClause.Expression = clause.From{Tables: v.Tables, Joins: v.Joins[:len(v.Joins)-len(db.Statement.Joins)]} // keep the original From Joins fromClause.Expression = clause.From{Tables: v.Tables, Joins: utils.RTrimSlice(v.Joins, len(db.Statement.Joins))} // keep the original From Joins
db.Statement.Clauses["FROM"] = fromClause db.Statement.Clauses["FROM"] = fromClause
} }
if db.Error == nil && db.Statement.Schema != nil && !db.Statement.SkipHooks && db.Statement.Schema.AfterFind && db.RowsAffected > 0 { if db.Error == nil && db.Statement.Schema != nil && !db.Statement.SkipHooks && db.Statement.Schema.AfterFind && db.RowsAffected > 0 {
......
...@@ -18,7 +18,6 @@ type Stmt struct { ...@@ -18,7 +18,6 @@ type Stmt struct {
type PreparedStmtDB struct { type PreparedStmtDB struct {
Stmts map[string]*Stmt Stmts map[string]*Stmt
PreparedSQL []string
Mux *sync.RWMutex Mux *sync.RWMutex
ConnPool ConnPool
} }
...@@ -28,7 +27,6 @@ func NewPreparedStmtDB(connPool ConnPool) *PreparedStmtDB { ...@@ -28,7 +27,6 @@ func NewPreparedStmtDB(connPool ConnPool) *PreparedStmtDB {
ConnPool: connPool, ConnPool: connPool,
Stmts: make(map[string]*Stmt), Stmts: make(map[string]*Stmt),
Mux: &sync.RWMutex{}, Mux: &sync.RWMutex{},
PreparedSQL: make([]string, 0, 100),
} }
} }
...@@ -48,12 +46,17 @@ func (db *PreparedStmtDB) Close() { ...@@ -48,12 +46,17 @@ func (db *PreparedStmtDB) Close() {
db.Mux.Lock() db.Mux.Lock()
defer db.Mux.Unlock() defer db.Mux.Unlock()
for _, query := range db.PreparedSQL { for _, stmt := range db.Stmts {
if stmt, ok := db.Stmts[query]; ok { go func(s *Stmt) {
delete(db.Stmts, query) // make sure the stmt must finish preparation first
go stmt.Close() <-s.prepared
if s.Stmt != nil {
_ = s.Close()
} }
}(stmt)
} }
// setting db.Stmts to nil to avoid further using
db.Stmts = nil
} }
func (sdb *PreparedStmtDB) Reset() { func (sdb *PreparedStmtDB) Reset() {
...@@ -61,9 +64,14 @@ func (sdb *PreparedStmtDB) Reset() { ...@@ -61,9 +64,14 @@ func (sdb *PreparedStmtDB) Reset() {
defer sdb.Mux.Unlock() defer sdb.Mux.Unlock()
for _, stmt := range sdb.Stmts { for _, stmt := range sdb.Stmts {
go stmt.Close() go func(s *Stmt) {
// make sure the stmt must finish preparation first
<-s.prepared
if s.Stmt != nil {
_ = s.Close()
}
}(stmt)
} }
sdb.PreparedSQL = make([]string, 0, 100)
sdb.Stmts = make(map[string]*Stmt) sdb.Stmts = make(map[string]*Stmt)
} }
...@@ -93,7 +101,12 @@ func (db *PreparedStmtDB) prepare(ctx context.Context, conn ConnPool, isTransact ...@@ -93,7 +101,12 @@ func (db *PreparedStmtDB) prepare(ctx context.Context, conn ConnPool, isTransact
return *stmt, nil return *stmt, nil
} }
// check db.Stmts first to avoid Segmentation Fault(setting value to nil map)
// which cause by calling Close and executing SQL concurrently
if db.Stmts == nil {
db.Mux.Unlock()
return Stmt{}, ErrInvalidDB
}
// cache preparing stmt first // cache preparing stmt first
cacheStmt := Stmt{Transaction: isTransaction, prepared: make(chan struct{})} cacheStmt := Stmt{Transaction: isTransaction, prepared: make(chan struct{})}
db.Stmts[query] = &cacheStmt db.Stmts[query] = &cacheStmt
...@@ -118,7 +131,6 @@ func (db *PreparedStmtDB) prepare(ctx context.Context, conn ConnPool, isTransact ...@@ -118,7 +131,6 @@ func (db *PreparedStmtDB) prepare(ctx context.Context, conn ConnPool, isTransact
db.Mux.Lock() db.Mux.Lock()
cacheStmt.Stmt = stmt cacheStmt.Stmt = stmt
db.PreparedSQL = append(db.PreparedSQL, query)
db.Mux.Unlock() db.Mux.Unlock()
return cacheStmt, nil return cacheStmt, nil
......
...@@ -166,3 +166,14 @@ func SplitNestedRelationName(name string) []string { ...@@ -166,3 +166,14 @@ func SplitNestedRelationName(name string) []string {
func JoinNestedRelationNames(relationNames []string) string { func JoinNestedRelationNames(relationNames []string) string {
return strings.Join(relationNames, nestedRelationSplit) return strings.Join(relationNames, nestedRelationSplit)
} }
// RTrimSlice Right trims the given slice by given length
func RTrimSlice[T any](v []T, trimLen int) []T {
if trimLen >= len(v) { // trimLen greater than slice len means fully sliced
return v[:0]
}
if trimLen < 0 { // negative trimLen is ignored
return v[:]
}
return v[:len(v)-trimLen]
}
...@@ -81,7 +81,7 @@ github.com/jinzhu/now ...@@ -81,7 +81,7 @@ github.com/jinzhu/now
# github.com/kr/fs v0.1.0 # github.com/kr/fs v0.1.0
## explicit ## explicit
github.com/kr/fs github.com/kr/fs
# github.com/lufia/plan9stats v0.0.0-20240819163618-b1d8f4d146e7 # github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683
## explicit; go 1.16 ## explicit; go 1.16
github.com/lufia/plan9stats github.com/lufia/plan9stats
# github.com/mattn/go-sqlite3 v1.14.17 # github.com/mattn/go-sqlite3 v1.14.17
...@@ -150,7 +150,7 @@ go.uber.org/zap/internal/exit ...@@ -150,7 +150,7 @@ go.uber.org/zap/internal/exit
go.uber.org/zap/internal/pool go.uber.org/zap/internal/pool
go.uber.org/zap/internal/stacktrace go.uber.org/zap/internal/stacktrace
go.uber.org/zap/zapcore go.uber.org/zap/zapcore
# golang.org/x/crypto v0.26.0 # golang.org/x/crypto v0.27.0
## explicit; go 1.20 ## explicit; go 1.20
golang.org/x/crypto/blowfish golang.org/x/crypto/blowfish
golang.org/x/crypto/chacha20 golang.org/x/crypto/chacha20
...@@ -169,12 +169,12 @@ golang.org/x/net/proxy ...@@ -169,12 +169,12 @@ golang.org/x/net/proxy
# golang.org/x/sync v0.8.0 # golang.org/x/sync v0.8.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/sync/errgroup golang.org/x/sync/errgroup
# golang.org/x/sys v0.24.0 # golang.org/x/sys v0.25.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/sys/cpu golang.org/x/sys/cpu
golang.org/x/sys/unix golang.org/x/sys/unix
golang.org/x/sys/windows golang.org/x/sys/windows
# golang.org/x/text v0.17.0 # golang.org/x/text v0.18.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/text/cases golang.org/x/text/cases
golang.org/x/text/internal golang.org/x/text/internal
...@@ -215,7 +215,7 @@ gorm.io/driver/mysql ...@@ -215,7 +215,7 @@ gorm.io/driver/mysql
# gorm.io/driver/sqlite v1.5.5 # gorm.io/driver/sqlite v1.5.5
## explicit; go 1.20 ## explicit; go 1.20
gorm.io/driver/sqlite gorm.io/driver/sqlite
# gorm.io/gorm v1.25.11 # gorm.io/gorm v1.25.12
## explicit; go 1.18 ## explicit; go 1.18
gorm.io/gorm gorm.io/gorm
gorm.io/gorm/callbacks gorm.io/gorm/callbacks
......
...@@ -246,6 +246,9 @@ func (w *LocalWorker) run(jobChannel chan GenericJob, stopChan chan bool, cancel ...@@ -246,6 +246,9 @@ func (w *LocalWorker) run(jobChannel chan GenericJob, stopChan chan bool, cancel
_ = w.manager.Sync(job) _ = w.manager.Sync(job)
} }
//eventBus := w.manager.GetEventBus()
//eventBus.Publish(JobDone, job.GetID())
}() }()
w.statisticMu.Lock() w.statisticMu.Lock()
......