// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn . //go:build plus package mmap import ( "io" "os" ) type SharedMMAP struct { filename string stat os.FileInfo rawReader *ReaderAt countRefs int32 mod uint64 } func NewSharedMMAP(filename string, stat os.FileInfo, reader *ReaderAt, mod uint64) *SharedMMAP { return &SharedMMAP{ filename: filename, stat: stat, rawReader: reader, countRefs: 1, mod: mod, } } func (this *SharedMMAP) ReadAt(p []byte, off int64) (n int, err error) { n, err = this.rawReader.ReadAt(p, off) return } func (this *SharedMMAP) Size() int64 { return this.stat.Size() } func (this *SharedMMAP) Stat() os.FileInfo { return this.stat } func (this *SharedMMAP) Name() string { return this.filename } // AddRef increase one reference func (this *SharedMMAP) AddRef() (ok bool) { mmapMapMu[this.mod].Lock() if this.countRefs > 0 { // not closing this.countRefs++ ok = true } mmapMapMu[this.mod].Unlock() return } func (this *SharedMMAP) Write(writer io.Writer, offset int) (int, error) { return this.rawReader.Write(writer, offset) } // Close release one reference // 单个引用 必须 只能close一次,防止提前close func (this *SharedMMAP) Close() error { if !enableShareMode { return this.rawReader.Close() } mmapMapMu[this.mod].Lock() this.countRefs-- var shouldClose = this.countRefs == 0 if shouldClose { var mmapMap = mmapMaps[this.mod] delete(mmapMap[this.filename], this) if len(mmapMap[this.filename]) == 0 { delete(mmapMap, this.filename) } } mmapMapMu[this.mod].Unlock() if shouldClose { return this.rawReader.Close() } return nil }